|
4 | 4 |
|
5 | 5 | import datetime |
6 | 6 | import functools |
| 7 | +import json |
7 | 8 | import logging |
8 | 9 | import os |
9 | 10 | import pathlib |
|
14 | 15 | import regex |
15 | 16 | import requests |
16 | 17 |
|
| 18 | +import snapshot_manager.config as config |
17 | 19 | import snapshot_manager.file_access as file_access |
18 | 20 |
|
19 | 21 |
|
@@ -474,3 +476,200 @@ def get_release_for_yyyymmdd(yyyymmdd: str) -> str: |
474 | 476 | logging.info(f"Getting URL {url}") |
475 | 477 | response = requests.get(url) |
476 | 478 | return response.text.strip() |
| 479 | + |
| 480 | + |
| 481 | +def filter_chroots(chroots: list[str], pattern: str) -> list[str]: |
| 482 | + """Return a sorted list of chroots filtered by the given pattern. |
| 483 | +
|
| 484 | + Args: |
| 485 | + chroots (list[str]): As list of chroots to filter |
| 486 | + pattern (str, optional): Regular expression e.g. `r"^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)"` |
| 487 | +
|
| 488 | + Returns: |
| 489 | + list[str]: List of filtered and sorted chroots. |
| 490 | +
|
| 491 | + Examples: |
| 492 | +
|
| 493 | + >>> chroots = ["rhel-7-x86_64", "rhel-9-s390x", "fedora-rawhide-x86_64", "centos-stream-10-ppc64le"] |
| 494 | + >>> filter_chroots(chroots=chroots, pattern=r"^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)") |
| 495 | + ['fedora-rawhide-x86_64', 'rhel-9-s390x'] |
| 496 | + """ |
| 497 | + res: list[str] = [] |
| 498 | + for chroot in chroots: |
| 499 | + if re.match(pattern=pattern, string=chroot) != None: |
| 500 | + res.append(chroot) |
| 501 | + res.sort() |
| 502 | + return res |
| 503 | + |
| 504 | + |
| 505 | +def sanitize_chroots(chroots: list[str]) -> list[str]: |
| 506 | + """Removes all s390x fedora chroots but rawhide and the highest |
| 507 | + numbered version in the given list |
| 508 | +
|
| 509 | + Args: |
| 510 | + chroots (list[str]): A list of chroots |
| 511 | +
|
| 512 | + Returns: |
| 513 | + list[str]: The sanitized list of chroots |
| 514 | +
|
| 515 | + Example: |
| 516 | +
|
| 517 | + >>> chroots = ["fedora-40-aarch64", "fedora-40-s390x", |
| 518 | + ... "fedora-41-s390x", "fedora-41-ppc64le", |
| 519 | + ... "fedora-42-aarch64", "fedora-42-s390x", |
| 520 | + ... "fedora-rawhide-x86_64", "fedora-rawhide-s390x", |
| 521 | + ... "rhel-8-aarch64", "rhel-8-s390x", |
| 522 | + ... "rhel-8-x86_64", "rhel-9-aarch64", |
| 523 | + ... "rhel-9-s390x", "rhel-9-x86_64"] |
| 524 | + >>> expected = ['fedora-40-aarch64', 'fedora-41-ppc64le', |
| 525 | + ... 'fedora-42-aarch64', 'fedora-42-s390x', |
| 526 | + ... 'fedora-rawhide-x86_64', 'fedora-rawhide-s390x', |
| 527 | + ... 'rhel-8-aarch64', 'rhel-8-s390x', |
| 528 | + ... 'rhel-8-x86_64', 'rhel-9-aarch64', |
| 529 | + ... 'rhel-9-s390x', 'rhel-9-x86_64'] |
| 530 | + >>> actual = sanitize_chroots(chroots) |
| 531 | + >>> actual == expected |
| 532 | + True |
| 533 | + """ |
| 534 | + chroots = [expect_chroot(chroot) for chroot in chroots] |
| 535 | + removals = filter_chroots(chroots, r"^fedora-[0-9]+-s390x") |
| 536 | + max = 0 |
| 537 | + for chroot in removals: |
| 538 | + ver = int(chroot_version(chroot)) |
| 539 | + if ver > max: |
| 540 | + max = ver |
| 541 | + for chroot in removals: |
| 542 | + if max != int(chroot_version(chroot)): |
| 543 | + chroots.remove(chroot) |
| 544 | + return chroots |
| 545 | + |
| 546 | + |
| 547 | +def augment_config_with_chroots(config: config.Config, all_chroots: list[str]) -> None: |
| 548 | + """Augments the config in place with chroots from the given chroot pattern. |
| 549 | +
|
| 550 | + Args: |
| 551 | + config (config.Config) A config object |
| 552 | + all_chroots (list[str]): A list of all possible chroots currently supported on Copr |
| 553 | +
|
| 554 | + Example: |
| 555 | +
|
| 556 | + >>> strategy = "foo" |
| 557 | + >>> all_chroots = ["fedora-rawhide-x86_64", "rhel-9-ppc64le", "fedora-42-x86_64"] |
| 558 | + >>> config = config.Config(build_strategy=strategy, chroot_pattern=r"fedora-.*") |
| 559 | + >>> augment_config_with_chroots(config=config, all_chroots=all_chroots) |
| 560 | + >>> config.chroots |
| 561 | + ['fedora-42-x86_64', 'fedora-rawhide-x86_64'] |
| 562 | + """ |
| 563 | + chroots = filter_chroots(chroots=all_chroots, pattern=config.chroot_pattern) |
| 564 | + config.chroots = sanitize_chroots(chroots=chroots) |
| 565 | + |
| 566 | + |
| 567 | +def augment_config_map_with_chroots( |
| 568 | + config_map: dict[str, config.Config], all_chroots: list[str] |
| 569 | +) -> None: |
| 570 | + """Augments the config_map in place with chroots from the given chroot pattern. |
| 571 | +
|
| 572 | + Args: |
| 573 | + config_map (dict[str, config.Config]) A config map as returned by config.build_config_map() |
| 574 | + all_chroots (list[str]): A list of all possible chroots currently supported on Copr |
| 575 | +
|
| 576 | + Example: |
| 577 | +
|
| 578 | + >>> all_chroots = ["fedora-rawhide-x86_64", "rhel-9-ppc64le", "fedora-42-x86_64"] |
| 579 | + >>> config_map = dict() |
| 580 | + >>> config_map["foo"] = config.Config(build_strategy="foo", chroot_pattern=r"fedora-.*") |
| 581 | + >>> config_map["bar"] = config.Config(build_strategy="bar", chroot_pattern=r"rhel-.*") |
| 582 | + >>> augment_config_map_with_chroots(config_map=config_map, all_chroots=all_chroots) |
| 583 | + >>> config_map["foo"].chroots |
| 584 | + ['fedora-42-x86_64', 'fedora-rawhide-x86_64'] |
| 585 | + >>> config_map["bar"].chroots |
| 586 | + ['rhel-9-ppc64le'] |
| 587 | + """ |
| 588 | + for strategy in config_map: |
| 589 | + augment_config_with_chroots( |
| 590 | + config=config_map[strategy], all_chroots=all_chroots |
| 591 | + ) |
| 592 | + |
| 593 | + |
| 594 | +def serialize_config_map_to_github_matrix( |
| 595 | + strategy: str, |
| 596 | + config_map: dict[str, config.Config], |
| 597 | + lookback_days: list[int] | None = None, |
| 598 | +) -> str: |
| 599 | + """Returns a serialized JSON github workflow matrix. |
| 600 | +
|
| 601 | + See https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow. |
| 602 | +
|
| 603 | + Args: |
| 604 | + strategy (str): Which strategy to output for for ("" or "all" will include all strategies from the `config_map`) |
| 605 | + config_map (dict[str, Config]): A config map to serialize |
| 606 | + lookback_days (list[int], optional): Integer array for how many days to look back (0 means just today) |
| 607 | +
|
| 608 | + Returns: |
| 609 | + str: A github workflow matrix dictionary as JSON |
| 610 | +
|
| 611 | + Example: |
| 612 | +
|
| 613 | + >>> strategy = "foo" |
| 614 | + >>> config_map = dict() |
| 615 | + >>> config_map["mybuildstrategy"] = config.Config(build_strategy="mybuildstrategy", |
| 616 | + ... copr_target_project="@mycoprgroup/mycoprproject", |
| 617 | + ... package_clone_url="https://src.fedoraproject.org/rpms/mypackage.git", |
| 618 | + ... package_clone_ref="mainbranch", |
| 619 | + ... maintainer_handle="fakeperson", |
| 620 | + ... copr_project_tpl="SomeProjectTemplate-YYYYMMDD", |
| 621 | + ... copr_monitor_tpl="https://copr.fedorainfracloud.org/coprs/g/mycoprgroup/SomeProjectTemplate-YYYYMMDD/monitor/", |
| 622 | + ... chroot_pattern="^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)", |
| 623 | + ... chroots=["fedora-rawhide-x86_64", "rhel-9-ppc64le"] |
| 624 | + ... ) |
| 625 | + >>> config_map["mybuildstrategy2"] = config.Config(build_strategy="mybuildstrategy2", |
| 626 | + ... copr_target_project="@mycoprgroup2/mycoprproject2", |
| 627 | + ... package_clone_url="https://src.fedoraproject.org/rpms/mypackage2.git", |
| 628 | + ... package_clone_ref="mainbranch2", |
| 629 | + ... maintainer_handle="fakeperson2", |
| 630 | + ... copr_project_tpl="SomeProjectTemplate2-YYYYMMDD", |
| 631 | + ... copr_monitor_tpl="https://copr.fedorainfracloud.org/coprs/g/mycoprgroup/SomeProjectTemplate2-YYYYMMDD/monitor/", |
| 632 | + ... chroot_pattern="rhel-[8,9]", |
| 633 | + ... chroots=["rhel-9-ppc64le"] |
| 634 | + ... ) |
| 635 | + >>> s = serialize_config_map_to_github_matrix(strategy="all", config_map=config_map, lookback_days=[0,1,2,3]) |
| 636 | + >>> obj = json.loads(s) |
| 637 | + >>> import pprint |
| 638 | + >>> pprint.pprint(obj) |
| 639 | + {'include': [{'chroot_pattern': '^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)', |
| 640 | + 'chroots': 'fedora-rawhide-x86_64 rhel-9-ppc64le', |
| 641 | + 'clone_ref': 'mainbranch', |
| 642 | + 'clone_url': 'https://src.fedoraproject.org/rpms/mypackage.git', |
| 643 | + 'copr_monitor_tpl': 'https://copr.fedorainfracloud.org/coprs/g/mycoprgroup/SomeProjectTemplate-YYYYMMDD/monitor/', |
| 644 | + 'copr_ownername': '@fedora-llvm-team', |
| 645 | + 'copr_project_tpl': 'SomeProjectTemplate-YYYYMMDD', |
| 646 | + 'copr_target_project': '@mycoprgroup/mycoprproject', |
| 647 | + 'maintainer_handle': 'fakeperson', |
| 648 | + 'name': 'mybuildstrategy'}, |
| 649 | + {'chroot_pattern': 'rhel-[8,9]', |
| 650 | + 'chroots': 'rhel-9-ppc64le', |
| 651 | + 'clone_ref': 'mainbranch2', |
| 652 | + 'clone_url': 'https://src.fedoraproject.org/rpms/mypackage2.git', |
| 653 | + 'copr_monitor_tpl': 'https://copr.fedorainfracloud.org/coprs/g/mycoprgroup/SomeProjectTemplate2-YYYYMMDD/monitor/', |
| 654 | + 'copr_ownername': '@fedora-llvm-team', |
| 655 | + 'copr_project_tpl': 'SomeProjectTemplate2-YYYYMMDD', |
| 656 | + 'copr_target_project': '@mycoprgroup2/mycoprproject2', |
| 657 | + 'maintainer_handle': 'fakeperson2', |
| 658 | + 'name': 'mybuildstrategy2'}], |
| 659 | + 'name': ['mybuildstrategy', 'mybuildstrategy2'], |
| 660 | + 'today_minus_n_days': [0, 1, 2, 3]} |
| 661 | + """ |
| 662 | + res = { |
| 663 | + "name": [], |
| 664 | + "include": [], |
| 665 | + } |
| 666 | + |
| 667 | + if lookback_days is not None: |
| 668 | + res["today_minus_n_days"] = lookback_days |
| 669 | + |
| 670 | + for strat in config_map: |
| 671 | + if strategy in ("all", "", strat): |
| 672 | + res["include"].append(config_map[strat].to_github_dict()) |
| 673 | + res["name"].append(strat) |
| 674 | + |
| 675 | + return json.dumps(res) |
0 commit comments