checkmk-dev-tools 2.2.0__tar.gz → 2.4.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.4.0}/PKG-INFO +2 -2
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/ci_artifacts.py +237 -90
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/version.py +1 -1
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/pyproject.toml +2 -2
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/README.md +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/__init__.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/activity_from_fs.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/binreplace.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/check_rpath.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/cli.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/cpumon.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/decent_output.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/jenkins_utils/__init__.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/job_resource_usage.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/last_access.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/lockable_resources.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/procmon.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.0}/cmk_dev/pycinfo.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.4.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.4.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.4.0/changelog.md
|
|
18
18
|
Project-URL: Repository, https://github.com/Checkmk/checkmk-dev-tools
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
|
|
@@ -14,8 +14,10 @@ import asyncio
|
|
|
14
14
|
import json
|
|
15
15
|
import logging
|
|
16
16
|
import os
|
|
17
|
+
import shutil
|
|
17
18
|
import sys
|
|
18
19
|
import time
|
|
20
|
+
import zipfile
|
|
19
21
|
from argparse import ArgumentParser
|
|
20
22
|
from argparse import Namespace as Args
|
|
21
23
|
from collections.abc import Mapping, MutableMapping, Sequence
|
|
@@ -24,7 +26,7 @@ from datetime import datetime
|
|
|
24
26
|
from itertools import chain
|
|
25
27
|
from pathlib import Path
|
|
26
28
|
from subprocess import check_output
|
|
27
|
-
from typing import Any, List, Literal, cast
|
|
29
|
+
from typing import Any, List, Literal, Set, TypedDict, cast
|
|
28
30
|
|
|
29
31
|
import requests
|
|
30
32
|
from influxdb_client import InfluxDBClient # type: ignore[attr-defined]
|
|
@@ -56,7 +58,14 @@ from .version import __version__
|
|
|
56
58
|
|
|
57
59
|
PathHashes = Mapping[str, str]
|
|
58
60
|
shared_build_info: asyncio.Queue[str] = asyncio.Queue(maxsize=1)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class FetchResult(TypedDict):
|
|
64
|
+
result: None | JobResult
|
|
65
|
+
artifacts: list[str]
|
|
66
|
+
|
|
59
67
|
MAX_RETRY_ATTEMPTS = 3
|
|
68
|
+
MAX_SINGLE_FILE_DOWNLOADS = 10 # max number of single files to be downloaded before using archive.zip + decompression
|
|
60
69
|
|
|
61
70
|
|
|
62
71
|
def parse_args() -> Args:
|
|
@@ -311,13 +320,11 @@ def download_artifacts(
|
|
|
311
320
|
total_download_timeout: int = 240,
|
|
312
321
|
no_remove_others: bool = False,
|
|
313
322
|
no_raise: bool = False,
|
|
314
|
-
) -> tuple[Sequence[str
|
|
323
|
+
) -> tuple[Sequence[str], Sequence[str]]:
|
|
315
324
|
"""Downloads all artifacts listed for given job/build to @out_dir"""
|
|
316
325
|
# pylint: disable=protected-access
|
|
317
326
|
# pylint: disable=too-many-locals
|
|
318
327
|
|
|
319
|
-
downloaded_artifacts, skipped_artifacts = [], []
|
|
320
|
-
|
|
321
328
|
# https://bugs.launchpad.net/python-jenkins/+bug/1973243
|
|
322
329
|
# https://bugs.launchpad.net/python-jenkins/+bug/2018576
|
|
323
330
|
|
|
@@ -358,6 +365,99 @@ def download_artifacts(
|
|
|
358
365
|
p.relative_to(out_dir).as_posix() for p in out_dir.glob("**/*") if p.is_file()
|
|
359
366
|
)
|
|
360
367
|
|
|
368
|
+
skipped_artifacts: List[str] = []
|
|
369
|
+
downloaded_artifacts: List[str] = []
|
|
370
|
+
if len(artifact_hashes) > MAX_SINGLE_FILE_DOWNLOADS:
|
|
371
|
+
downloaded_artifact = _download_compressed_artifacs(
|
|
372
|
+
client=client,
|
|
373
|
+
build=build,
|
|
374
|
+
existing_files=existing_files,
|
|
375
|
+
artifact_hashes=artifact_hashes,
|
|
376
|
+
out_dir=out_dir,
|
|
377
|
+
total_download_timeout=total_download_timeout,
|
|
378
|
+
)
|
|
379
|
+
downloaded_artifacts.append(downloaded_artifact)
|
|
380
|
+
downloaded_artifacts.extend(_decompress_artifacts(
|
|
381
|
+
artifact=out_dir / downloaded_artifact,
|
|
382
|
+
out_dir=out_dir,
|
|
383
|
+
))
|
|
384
|
+
else:
|
|
385
|
+
downloaded_artifacts, skipped_artifacts, existing_files = _download_individual_artifacts(
|
|
386
|
+
client=client,
|
|
387
|
+
build=build,
|
|
388
|
+
existing_files=existing_files,
|
|
389
|
+
artifact_hashes=artifact_hashes,
|
|
390
|
+
out_dir=out_dir,
|
|
391
|
+
total_download_timeout=total_download_timeout,
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
if not no_remove_others:
|
|
395
|
+
for path in existing_files - set(downloaded_artifacts) - set(skipped_artifacts):
|
|
396
|
+
log().debug("Remove superfluous file %s", path)
|
|
397
|
+
with suppress(FileNotFoundError):
|
|
398
|
+
(out_dir / path).unlink()
|
|
399
|
+
log().info(
|
|
400
|
+
"%d artifacts available in '%s' (%d skipped, because they were up to date locally)",
|
|
401
|
+
len(downloaded_artifacts) + len(skipped_artifacts),
|
|
402
|
+
out_dir,
|
|
403
|
+
len(skipped_artifacts),
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
return downloaded_artifacts, skipped_artifacts
|
|
407
|
+
|
|
408
|
+
def _download_compressed_artifacs(
|
|
409
|
+
client: Jenkins,
|
|
410
|
+
build: Build,
|
|
411
|
+
existing_files: Set[str],
|
|
412
|
+
artifact_hashes: Mapping[str, str],
|
|
413
|
+
out_dir: Path,
|
|
414
|
+
total_download_timeout: int = 240,
|
|
415
|
+
) -> str:
|
|
416
|
+
|
|
417
|
+
# https://ci.lan.tribe29.com/job/checkmk/job/master/job/cv/job/test-gerrit-single-k8s/710903/artifact/*zip*/archive.zip
|
|
418
|
+
artifact = "archive.zip"
|
|
419
|
+
artifact_filename = out_dir / artifact
|
|
420
|
+
|
|
421
|
+
# ignore the returned value of the function as it would be like "/*zip*/archive.zip"
|
|
422
|
+
_download_single_file(
|
|
423
|
+
client=client,
|
|
424
|
+
build=build,
|
|
425
|
+
artifact=f"/*zip*/{artifact}",
|
|
426
|
+
artifact_filename=artifact_filename,
|
|
427
|
+
total_download_timeout=total_download_timeout,
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
return artifact
|
|
431
|
+
|
|
432
|
+
def _decompress_artifacts(artifact: Path, out_dir: Path, decompressed_folder_name: str = "archive") -> List[str]:
|
|
433
|
+
with zipfile.ZipFile(artifact, "r") as zip_ref:
|
|
434
|
+
zip_ref.extractall(out_dir)
|
|
435
|
+
|
|
436
|
+
# The extracted folder is always named "archive"
|
|
437
|
+
archive_dir = out_dir / decompressed_folder_name
|
|
438
|
+
|
|
439
|
+
downloaded_artifacts = []
|
|
440
|
+
|
|
441
|
+
# Move all contents of the decompressed archive folder up one level
|
|
442
|
+
if archive_dir.exists() and archive_dir.is_dir():
|
|
443
|
+
for item in archive_dir.iterdir():
|
|
444
|
+
shutil.copytree(str(item), str(out_dir / item.name), dirs_exist_ok=True)
|
|
445
|
+
downloaded_artifacts += [str(f.relative_to(out_dir)) for f in (out_dir / item.name).rglob("*") if f.is_file()]
|
|
446
|
+
|
|
447
|
+
shutil.rmtree(archive_dir)
|
|
448
|
+
|
|
449
|
+
return downloaded_artifacts
|
|
450
|
+
|
|
451
|
+
def _download_individual_artifacts(
|
|
452
|
+
client: Jenkins,
|
|
453
|
+
build: Build,
|
|
454
|
+
existing_files: Set[str],
|
|
455
|
+
artifact_hashes: Mapping[str, str],
|
|
456
|
+
out_dir: Path,
|
|
457
|
+
total_download_timeout: int = 240,
|
|
458
|
+
) -> tuple[List[str], List[str], Set[str]]:
|
|
459
|
+
downloaded_artifacts, skipped_artifacts = [], []
|
|
460
|
+
|
|
361
461
|
for artifact in build.artifacts:
|
|
362
462
|
existing_files -= {artifact}
|
|
363
463
|
fp_hash = artifact_hashes[artifact]
|
|
@@ -378,54 +478,62 @@ def download_artifacts(
|
|
|
378
478
|
fp_hash,
|
|
379
479
|
)
|
|
380
480
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
for chunk in reply.iter_content(chunk_size=8192):
|
|
391
|
-
if (
|
|
392
|
-
current_dl_duration := (time.time() - time_start)
|
|
393
|
-
) > total_download_timeout:
|
|
394
|
-
raise TimeoutError(
|
|
395
|
-
f"Downloading of {reply.url} took longer than {total_download_timeout}s"
|
|
396
|
-
)
|
|
397
|
-
if chunk: # Filter out keep-alive chunks
|
|
398
|
-
out_file.write(chunk)
|
|
399
|
-
log().debug(
|
|
400
|
-
"download: %s - successful (took %.2fs)", artifact, current_dl_duration
|
|
401
|
-
)
|
|
402
|
-
downloaded_artifacts.append(artifact)
|
|
403
|
-
break
|
|
404
|
-
except (
|
|
405
|
-
requests.exceptions.ChunkedEncodingError,
|
|
406
|
-
requests.exceptions.ConnectionError,
|
|
407
|
-
TimeoutError,
|
|
408
|
-
) as exc:
|
|
409
|
-
if not attempts_left:
|
|
410
|
-
raise
|
|
411
|
-
log().warning(
|
|
412
|
-
"download_artifacts() caught %r (%s retries left)", exc, attempts_left
|
|
413
|
-
)
|
|
481
|
+
downloaded_artifacts.append(
|
|
482
|
+
_download_single_file(
|
|
483
|
+
client=client,
|
|
484
|
+
build=build,
|
|
485
|
+
artifact=artifact,
|
|
486
|
+
artifact_filename=artifact_filename,
|
|
487
|
+
total_download_timeout=total_download_timeout,
|
|
488
|
+
)
|
|
489
|
+
)
|
|
414
490
|
|
|
415
|
-
|
|
416
|
-
for path in existing_files - set(downloaded_artifacts) - set(skipped_artifacts):
|
|
417
|
-
log().debug("Remove superfluous file %s", path)
|
|
418
|
-
with suppress(FileNotFoundError):
|
|
419
|
-
(out_dir / path).unlink()
|
|
420
|
-
log().info(
|
|
421
|
-
"%d artifacts available in '%s' (%d skipped, because they were up to date locally)",
|
|
422
|
-
len(downloaded_artifacts) + len(skipped_artifacts),
|
|
423
|
-
out_dir,
|
|
424
|
-
len(skipped_artifacts),
|
|
425
|
-
)
|
|
491
|
+
return downloaded_artifacts, skipped_artifacts, existing_files
|
|
426
492
|
|
|
427
|
-
|
|
493
|
+
def _download_single_file(
|
|
494
|
+
client: Jenkins,
|
|
495
|
+
build: Build,
|
|
496
|
+
artifact: str,
|
|
497
|
+
artifact_filename: Path,
|
|
498
|
+
total_download_timeout: int = 240,
|
|
499
|
+
) -> str:
|
|
500
|
+
downloaded_artifact: str = ""
|
|
501
|
+
|
|
502
|
+
for attempts_left in reversed(range(MAX_RETRY_ATTEMPTS + 1)):
|
|
503
|
+
time_start = time.time()
|
|
504
|
+
try:
|
|
505
|
+
with client._session.get(f"{build.url}artifact/{artifact}", stream=True) as reply:
|
|
506
|
+
log().debug("download: %s", artifact)
|
|
507
|
+
reply.raise_for_status()
|
|
508
|
+
artifact_filename.parent.mkdir(parents=True, exist_ok=True)
|
|
509
|
+
current_dl_duration = 0.0
|
|
510
|
+
with open(artifact_filename, "wb") as out_file:
|
|
511
|
+
for chunk in reply.iter_content(chunk_size=8192):
|
|
512
|
+
if (
|
|
513
|
+
current_dl_duration := (time.time() - time_start)
|
|
514
|
+
) > total_download_timeout:
|
|
515
|
+
raise TimeoutError(
|
|
516
|
+
f"Downloading of {reply.url} took longer than {total_download_timeout}s"
|
|
517
|
+
)
|
|
518
|
+
if chunk: # Filter out keep-alive chunks
|
|
519
|
+
out_file.write(chunk)
|
|
520
|
+
log().debug(
|
|
521
|
+
"download: %s - successful (took %.2fs)", artifact, current_dl_duration
|
|
522
|
+
)
|
|
523
|
+
downloaded_artifact = artifact
|
|
524
|
+
break
|
|
525
|
+
except (
|
|
526
|
+
requests.exceptions.ChunkedEncodingError,
|
|
527
|
+
requests.exceptions.ConnectionError,
|
|
528
|
+
TimeoutError,
|
|
529
|
+
) as exc:
|
|
530
|
+
if not attempts_left:
|
|
531
|
+
raise
|
|
532
|
+
log().warning(
|
|
533
|
+
"download_artifacts() caught %r (%s retries left)", exc, attempts_left
|
|
534
|
+
)
|
|
428
535
|
|
|
536
|
+
return downloaded_artifact
|
|
429
537
|
|
|
430
538
|
def path_hashes_match(actual: PathHashes, required: PathHashes) -> bool:
|
|
431
539
|
"""Returns True if two given path hash mappings are semantically equal, i.e. at least one hash
|
|
@@ -733,6 +841,7 @@ async def _fn_request_build(args: Args) -> None:
|
|
|
733
841
|
path_hashes=compose_path_hashes(args.base_dir, args.dependency_paths),
|
|
734
842
|
time_constraints=args.time_constraints,
|
|
735
843
|
next_check_sleep=args.poll_queue_sleep,
|
|
844
|
+
ignore_build_queue=args.ignore_build_queue,
|
|
736
845
|
args=args,
|
|
737
846
|
)
|
|
738
847
|
):
|
|
@@ -901,54 +1010,72 @@ def query_matching_builds(
|
|
|
901
1010
|
return []
|
|
902
1011
|
|
|
903
1012
|
|
|
904
|
-
async def
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1013
|
+
async def fetch_artifacts(
|
|
1014
|
+
job: str,
|
|
1015
|
+
params: None | JobParams = None,
|
|
1016
|
+
*,
|
|
1017
|
+
out_dir: Path = Path("out"),
|
|
1018
|
+
base_dir: Path = Path("."),
|
|
1019
|
+
params_no_check: None | JobParams = None,
|
|
1020
|
+
dependency_paths: None | Sequence[str] = None,
|
|
1021
|
+
time_constraints: None | str = None,
|
|
1022
|
+
force_new_build: bool = False,
|
|
1023
|
+
omit_new_build: bool = False,
|
|
1024
|
+
download: bool = True,
|
|
1025
|
+
no_remove_others: bool = False,
|
|
1026
|
+
no_raise: bool = False,
|
|
1027
|
+
poll_queue_sleep: int = 30,
|
|
1028
|
+
poll_sleep: int = 60,
|
|
1029
|
+
timeout: int = 120,
|
|
1030
|
+
total_download_timeout: int = 240,
|
|
1031
|
+
credentials: None | Mapping[str, str] = None,
|
|
1032
|
+
credentials_file: str = "~/.config/jenkins_jobs/jenkins_jobs.ini",
|
|
1033
|
+
) -> FetchResult:
|
|
1034
|
+
"""Find or trigger a matching build, wait for it, download artifacts, return result dict."""
|
|
1035
|
+
resolved_out_dir = compose_out_dir(base_dir, out_dir)
|
|
1036
|
+
path_hashes = compose_path_hashes(base_dir, dependency_paths or [])
|
|
908
1037
|
async with AugmentedJenkinsClient(
|
|
909
|
-
**extract_credentials(
|
|
1038
|
+
**extract_credentials(credentials, credentials_file=credentials_file), timeout=timeout
|
|
910
1039
|
) 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
|
|
1040
|
+
if not (job_info := await jenkins_client.job_info(job)).type == "WorkflowJob":
|
|
1041
|
+
raise Fatal(f"{job} is not a WorkflowJob")
|
|
914
1042
|
matching_build = (
|
|
915
1043
|
None
|
|
916
|
-
if
|
|
1044
|
+
if force_new_build
|
|
917
1045
|
else await identify_matching_build(
|
|
918
|
-
|
|
1046
|
+
job_info,
|
|
919
1047
|
jenkins_client=jenkins_client,
|
|
920
|
-
params=
|
|
921
|
-
path_hashes=
|
|
922
|
-
time_constraints=
|
|
923
|
-
next_check_sleep=
|
|
924
|
-
args=args,
|
|
1048
|
+
params=params,
|
|
1049
|
+
path_hashes=path_hashes,
|
|
1050
|
+
time_constraints=time_constraints,
|
|
1051
|
+
next_check_sleep=poll_queue_sleep,
|
|
925
1052
|
)
|
|
926
1053
|
)
|
|
927
|
-
if
|
|
928
|
-
raise Fatal(
|
|
929
|
-
|
|
1054
|
+
if omit_new_build and not matching_build:
|
|
1055
|
+
raise Fatal(
|
|
1056
|
+
f"No matching build found for job '{job_info.name}' but new builds are omitted."
|
|
1057
|
+
)
|
|
930
1058
|
build_candidate = matching_build or await trigger_build(
|
|
931
1059
|
jenkins_client=jenkins_client,
|
|
932
|
-
job=
|
|
1060
|
+
job=job_info,
|
|
933
1061
|
params=compose_build_params(
|
|
934
|
-
params=
|
|
935
|
-
params_no_check=
|
|
936
|
-
path_hashes=
|
|
1062
|
+
params=params,
|
|
1063
|
+
params_no_check=params_no_check,
|
|
1064
|
+
path_hashes=path_hashes,
|
|
937
1065
|
),
|
|
938
|
-
next_check_sleep=
|
|
1066
|
+
next_check_sleep=poll_queue_sleep,
|
|
939
1067
|
)
|
|
940
|
-
|
|
941
1068
|
for key, value in build_candidate.__dict__.items():
|
|
942
1069
|
log().debug(" %s: %s", key, value)
|
|
943
|
-
|
|
944
1070
|
completed_build = await await_build(
|
|
945
|
-
|
|
1071
|
+
job_info.path,
|
|
946
1072
|
build_candidate.number,
|
|
947
1073
|
jenkins_client=jenkins_client,
|
|
948
1074
|
check_result=True,
|
|
949
1075
|
path_hashes=path_hashes,
|
|
950
|
-
next_check_sleep=
|
|
951
|
-
no_raise=
|
|
1076
|
+
next_check_sleep=poll_sleep,
|
|
1077
|
+
no_raise=no_raise,
|
|
1078
|
+
download=download,
|
|
952
1079
|
)
|
|
953
1080
|
downloaded_artifacts = (
|
|
954
1081
|
list(
|
|
@@ -956,25 +1083,44 @@ async def _fn_fetch(args: Args) -> None:
|
|
|
956
1083
|
*download_artifacts(
|
|
957
1084
|
jenkins_client.client,
|
|
958
1085
|
completed_build,
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1086
|
+
resolved_out_dir,
|
|
1087
|
+
total_download_timeout,
|
|
1088
|
+
no_remove_others,
|
|
1089
|
+
no_raise,
|
|
963
1090
|
)
|
|
964
1091
|
)
|
|
965
1092
|
)
|
|
966
|
-
if
|
|
1093
|
+
if download
|
|
967
1094
|
else []
|
|
968
1095
|
)
|
|
1096
|
+
return {"result": completed_build.result, "artifacts": downloaded_artifacts}
|
|
969
1097
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1098
|
+
|
|
1099
|
+
async def _fn_fetch(args: Args) -> None:
|
|
1100
|
+
"""Entry point for fetching (request and download combined) artifacts"""
|
|
1101
|
+
print(
|
|
1102
|
+
json.dumps(
|
|
1103
|
+
await fetch_artifacts(
|
|
1104
|
+
job=args.job,
|
|
1105
|
+
params=flatten(args.params),
|
|
1106
|
+
out_dir=args.out_dir,
|
|
1107
|
+
base_dir=args.base_dir,
|
|
1108
|
+
params_no_check=flatten(args.params_no_check),
|
|
1109
|
+
dependency_paths=args.dependency_paths,
|
|
1110
|
+
time_constraints=args.time_constraints,
|
|
1111
|
+
force_new_build=args.force_new_build,
|
|
1112
|
+
omit_new_build=args.omit_new_build,
|
|
1113
|
+
download=args.download,
|
|
1114
|
+
no_remove_others=args.no_remove_others,
|
|
1115
|
+
no_raise=args.no_raise,
|
|
1116
|
+
poll_queue_sleep=args.poll_queue_sleep,
|
|
1117
|
+
poll_sleep=args.poll_sleep,
|
|
1118
|
+
timeout=args.timeout,
|
|
1119
|
+
total_download_timeout=args.total_download_timeout,
|
|
1120
|
+
credentials=args.credentials,
|
|
976
1121
|
)
|
|
977
1122
|
)
|
|
1123
|
+
)
|
|
978
1124
|
|
|
979
1125
|
|
|
980
1126
|
async def identify_matching_build(
|
|
@@ -985,6 +1131,7 @@ async def identify_matching_build(
|
|
|
985
1131
|
path_hashes: PathHashes,
|
|
986
1132
|
time_constraints: None | str,
|
|
987
1133
|
next_check_sleep: int = 30,
|
|
1134
|
+
ignore_build_queue: bool = False,
|
|
988
1135
|
args: None | Args = None,
|
|
989
1136
|
) -> None | Build:
|
|
990
1137
|
"""Find an existing build (finished, still running or queued) which matches our
|
|
@@ -1102,7 +1249,7 @@ async def identify_matching_build(
|
|
|
1102
1249
|
log().info("No matching builds found in the InfluxDB")
|
|
1103
1250
|
|
|
1104
1251
|
log().info("Check for matching queue items via Jenkins API")
|
|
1105
|
-
if
|
|
1252
|
+
if not ignore_build_queue:
|
|
1106
1253
|
if matching_item := await find_matching_queue_item(
|
|
1107
1254
|
jenkins_client=jenkins_client,
|
|
1108
1255
|
job=job,
|
|
@@ -1143,7 +1290,7 @@ async def identify_matching_build(
|
|
|
1143
1290
|
log().info("No matching non finished builds found via the Jenkins API")
|
|
1144
1291
|
|
|
1145
1292
|
log().info("Check for matching queue items via Jenkins API")
|
|
1146
|
-
if
|
|
1293
|
+
if not ignore_build_queue:
|
|
1147
1294
|
if matching_item := await find_matching_queue_item(
|
|
1148
1295
|
jenkins_client=jenkins_client,
|
|
1149
1296
|
job=job,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "checkmk-dev-tools"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.4.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.4.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
|