diff --git a/.gitignore b/.gitignore index 0bb92d3d..a04c7ded 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,7 @@ ENV/ # visual studio code configuration .vscode +*.code-workspace # pycharm .idea diff --git a/.packit.yaml b/.packit.yaml index 75788a25..607dff93 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -168,6 +168,7 @@ jobs: env: SOURCE_RELEASE: "8.10" TARGET_RELEASE: "9.4" + LEAPP_TARGET_PRODUCT_CHANNEL: "EUS" # On-demand minimal beaker tests - &beaker-minimal-810to94 @@ -194,6 +195,7 @@ jobs: env: SOURCE_RELEASE: "8.10" TARGET_RELEASE: "9.4" + LEAPP_TARGET_PRODUCT_CHANNEL: "EUS" # On-demand kernel-rt tests - &kernel-rt-810to94 @@ -220,6 +222,7 @@ jobs: env: SOURCE_RELEASE: "8.10" TARGET_RELEASE: "9.4" + LEAPP_TARGET_PRODUCT_CHANNEL: "EUS" # Tests: 8.10 -> 9.6 - &sanity-810to96 @@ -295,6 +298,80 @@ jobs: SOURCE_RELEASE: "8.10" TARGET_RELEASE: "9.6" +# Tests: 8.10 -> 9.7 +- &sanity-810to97 + <<: *sanity-abstract-8to9 + trigger: pull_request + identifier: sanity-8.10to9.7 + tf_extra_params: + test: + tmt: + plan_filter: 'tag:8to9 & tag:tier0 & enabled:true' + environments: + - tmt: + context: + distro: "rhel-8.10" + distro_target: "rhel-9.7" + settings: + provisioning: + tags: + BusinessUnit: sst_upgrades@leapp_upstream_test + env: + SOURCE_RELEASE: "8.10" + TARGET_RELEASE: "9.7" + +# On-demand minimal beaker tests +- &beaker-minimal-810to97 + <<: *beaker-minimal-8to9-abstract-ondemand + trigger: pull_request + labels: + - beaker-minimal + - beaker-minimal-8.10to9.7 + - 8.10to9.7 + identifier: sanity-8.10to9.7-beaker-minimal-ondemand + tf_extra_params: + test: + tmt: + plan_filter: 'tag:8to9 & tag:partitioning & enabled:true' + environments: + - tmt: + context: + distro: "rhel-8.10" + distro_target: "rhel-9.7" + settings: + provisioning: + tags: + BusinessUnit: sst_upgrades@leapp_upstream_test + env: + SOURCE_RELEASE: "8.10" + TARGET_RELEASE: "9.7" + +# On-demand kernel-rt tests +- &kernel-rt-810to97 + <<: *kernel-rt-abstract-8to9-ondemand + trigger: pull_request + labels: + - kernel-rt + - kernel-rt-8.10to9.7 + - 8.10to9.7 + identifier: sanity-8.10to9.7-kernel-rt-ondemand + tf_extra_params: + test: + tmt: + plan_filter: 'tag:8to9 & tag:kernel-rt & enabled:true' + environments: + - tmt: + context: + distro: "rhel-8.10" + distro_target: "rhel-9.7" + settings: + provisioning: + tags: + BusinessUnit: sst_upgrades@leapp_upstream_test + env: + SOURCE_RELEASE: "8.10" + TARGET_RELEASE: "9.7" + # ###################################################################### # # ############################## 9 TO 10 ################################ # # ###################################################################### # @@ -351,6 +428,9 @@ jobs: <<: *sanity-abstract-9to10 trigger: pull_request identifier: sanity-9.6to10.0 + targets: + epel-9-x86_64: + distros: [RHEL-9.6.0-Nightly] tf_extra_params: test: tmt: @@ -377,6 +457,9 @@ jobs: - beaker-minimal-9.6to10.0 - 9.6to10.0 identifier: sanity-9.6to10.0-beaker-minimal-ondemand + targets: + epel-9-x86_64: + distros: [RHEL-9.6-Nightly] tf_extra_params: test: tmt: @@ -419,3 +502,86 @@ jobs: env: SOURCE_RELEASE: "9.6" TARGET_RELEASE: "10.0" + +# Tests: 9.7 -> 10.1 +- &sanity-97to101 + <<: *sanity-abstract-9to10 + trigger: pull_request + identifier: sanity-9.7to10.1 + targets: + epel-9-x86_64: + distros: [RHEL-9.7.0-Nightly] + tf_extra_params: + test: + tmt: + plan_filter: 'tag:9to10 & tag:tier0 & enabled:true' + environments: + - tmt: + context: + distro: "rhel-9.7" + distro_target: "rhel-10.1" + settings: + provisioning: + tags: + BusinessUnit: sst_upgrades@leapp_upstream_test + env: + SOURCE_RELEASE: "9.7" + TARGET_RELEASE: "10.1" + +# On-demand minimal beaker tests +- &beaker-minimal-97to101 + <<: *beaker-minimal-9to10-abstract-ondemand + trigger: pull_request + labels: + - beaker-minimal + - beaker-minimal-9.7to10.1 + - 9.7to10.1 + identifier: sanity-9.7to10.1-beaker-minimal-ondemand + targets: + epel-9-x86_64: + distros: [RHEL-9.7-Nightly] + tf_extra_params: + test: + tmt: + plan_filter: 'tag:8to9 & tag:partitioning & enabled:true' + environments: + - tmt: + context: + distro: "rhel-9.7" + distro_target: "rhel-10.1" + settings: + provisioning: + tags: + BusinessUnit: sst_upgrades@leapp_upstream_test + env: + SOURCE_RELEASE: "9.7" + TARGET_RELEASE: "10.1" + +# On-demand kernel-rt tests +- &kernel-rt-97to101 + <<: *kernel-rt-abstract-9to10-ondemand + trigger: pull_request + labels: + - kernel-rt + - kernel-rt-9.7to10.1 + - 9.7to10.1 + identifier: sanity-9.7to10.1-kernel-rt-ondemand + targets: + epel-9-x86_64: + distros: [RHEL-9.7-Nightly] + tf_extra_params: + test: + tmt: + plan_filter: 'tag:8to9 & tag:kernel-rt & enabled:true' + environments: + - tmt: + context: + distro: "rhel-9.7" + distro_target: "rhel-10.1" + settings: + provisioning: + tags: + BusinessUnit: sst_upgrades@leapp_upstream_test + env: + SOURCE_RELEASE: "9.7" + TARGET_RELEASE: "10.1" diff --git a/Makefile b/Makefile index 3d9f2857..81b16376 100644 --- a/Makefile +++ b/Makefile @@ -496,6 +496,7 @@ fast_lint: @. $(VENVNAME)/bin/activate; \ FILES_TO_LINT="$$(git diff --name-only $(MASTER_BRANCH) --diff-filter AMR | grep '\.py$$')"; \ if [[ -n "$$FILES_TO_LINT" ]]; then \ + isort -c --diff $$FILES_TO_LINT && \ pylint -j 0 $$FILES_TO_LINT $(PYLINT_ARGS) && \ flake8 $$FILES_TO_LINT $(FLAKE8_ARGS); \ LINT_EXIT_CODE="$$?"; \ diff --git a/ci/.gitignore b/ci/.gitignore new file mode 100644 index 00000000..e6f97f0f --- /dev/null +++ b/ci/.gitignore @@ -0,0 +1 @@ +**/.vagrant diff --git a/ci/ansible/ansible.cfg b/ci/ansible/ansible.cfg new file mode 100644 index 00000000..d5c13036 --- /dev/null +++ b/ci/ansible/ansible.cfg @@ -0,0 +1,4 @@ +[defaults] +callbacks_enabled=ansible.posix.profile_tasks +stdout_callback=community.general.yaml +pipelining=True diff --git a/ci/ansible/docker-ce.yaml b/ci/ansible/docker-ce.yaml new file mode 100644 index 00000000..bba5f3df --- /dev/null +++ b/ci/ansible/docker-ce.yaml @@ -0,0 +1,6 @@ +--- +- name: Docker CE configuration + hosts: all + become: yes + roles: + - docker-ce diff --git a/ci/ansible/minimal.yaml b/ci/ansible/minimal.yaml new file mode 100644 index 00000000..517cc81b --- /dev/null +++ b/ci/ansible/minimal.yaml @@ -0,0 +1,6 @@ +--- +- name: Minimal configuration + hosts: all + become: yes + roles: + - minimal diff --git a/ci/ansible/requirements.yaml b/ci/ansible/requirements.yaml new file mode 100644 index 00000000..13ca0224 --- /dev/null +++ b/ci/ansible/requirements.yaml @@ -0,0 +1,3 @@ +collections: + - name: community.general + - name: ansible.posix diff --git a/ci/ansible/roles/docker-ce/README.md b/ci/ansible/roles/docker-ce/README.md new file mode 100644 index 00000000..860444b1 --- /dev/null +++ b/ci/ansible/roles/docker-ce/README.md @@ -0,0 +1,43 @@ +Docker CE Install and configuration +========= + +Install latest version of Docker CE Engine form upstream repository. Start and enable services after installation. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +`docker_ce_repo_checksum` in defaults/main.yaml. SHA512 Checksum of the docker-ce.repo file. +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: all + become: yes + roles: + - role: docker + vars: + docker_ce_repo_checksum: sha512:XXXX # You can provide the new checksum if the default one not actual + + +License +------- + +GPL-3.0-or-later + +Author Information +------------------ + +AlmaLinux OS Foundation diff --git a/ci/ansible/roles/docker-ce/defaults/main.yaml b/ci/ansible/roles/docker-ce/defaults/main.yaml new file mode 100644 index 00000000..d0fd0c09 --- /dev/null +++ b/ci/ansible/roles/docker-ce/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +# defaults file for docker-ce +docker_ce_repo_checksum: sha512:1de0b99cbb427e974144f226451711dc491caef6b1256cb599ff307a687ba2d7dd959a016d4e4cfdd4acbd83423ba1f78fa89db61bab35351e35f1152aedaf5c diff --git a/ci/ansible/roles/docker-ce/handlers/main.yaml b/ci/ansible/roles/docker-ce/handlers/main.yaml new file mode 100644 index 00000000..a7236219 --- /dev/null +++ b/ci/ansible/roles/docker-ce/handlers/main.yaml @@ -0,0 +1,2 @@ +--- +# handlers file for docker-ce diff --git a/ci/ansible/roles/docker-ce/meta/main.yaml b/ci/ansible/roles/docker-ce/meta/main.yaml new file mode 100644 index 00000000..aa67ded8 --- /dev/null +++ b/ci/ansible/roles/docker-ce/meta/main.yaml @@ -0,0 +1,25 @@ +galaxy_info: + author: AlmaLinux OS Community + description: Install and configure Docker CE Engine + company: AlmaLinux OS Foundation + + license: GPL-3.0-or-later + + min_ansible_version: 2.11 + + platforms: + - name: EL + versions: + - 7 + - 8 + - 9 + + galaxy_tags: + - docker + - el7 + - el8 + - el9 + - almalinux + +dependencies: + - minimal diff --git a/ci/ansible/roles/docker-ce/tasks/install_docker_el7.yaml b/ci/ansible/roles/docker-ce/tasks/install_docker_el7.yaml new file mode 100644 index 00000000..320477af --- /dev/null +++ b/ci/ansible/roles/docker-ce/tasks/install_docker_el7.yaml @@ -0,0 +1,11 @@ +--- +# Install Docker +- name: Install Docker CE Stable + ansible.builtin.yum: + name: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-compose-plugin + update_cache: yes + state: present diff --git a/ci/ansible/roles/docker-ce/tasks/install_docker_el8.yaml b/ci/ansible/roles/docker-ce/tasks/install_docker_el8.yaml new file mode 100644 index 00000000..d44a202a --- /dev/null +++ b/ci/ansible/roles/docker-ce/tasks/install_docker_el8.yaml @@ -0,0 +1,11 @@ +--- +# Install Docker +- name: Install Docker CE Stable + ansible.builtin.dnf: + name: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-compose-plugin + update_cache: yes + state: present diff --git a/ci/ansible/roles/docker-ce/tasks/main.yaml b/ci/ansible/roles/docker-ce/tasks/main.yaml new file mode 100644 index 00000000..989af23f --- /dev/null +++ b/ci/ansible/roles/docker-ce/tasks/main.yaml @@ -0,0 +1,38 @@ +--- +# tasks file for docker-ce +- name: Add Docker CE repository + ansible.builtin.get_url: + url: https://download.docker.com/linux/centos/docker-ce.repo + dest: /etc/yum.repos.d/docker-ce.repo + checksum: "{{ docker_ce_repo_checksum }}" + owner: root + group: root + mode: '0644' + seuser: system_u + serole: object_r + setype: system_conf_t + +- name: Remove older versions of Docker on EL7 + ansible.builtin.include_tasks: remove_old_docker_el7.yaml + when: ansible_facts['distribution_major_version'] == '7' + +- name: Remove older versions of Docker on >= EL8 + ansible.builtin.include_tasks: remove_old_docker_el8.yaml + when: ansible_facts['distribution_major_version'] == '8' + +- name: Install Docker CE Stable on EL7 + ansible.builtin.include_tasks: install_docker_el7.yaml + when: ansible_facts['distribution_major_version'] == '7' + +- name: Install Docker CE Stable on >= EL8 + ansible.builtin.include_tasks: install_docker_el8.yaml + when: ansible_facts['distribution_major_version'] == '8' + +- name: Start and Enable Docker services + ansible.builtin.systemd: + name: "{{ item }}" + enabled: yes + state: started + loop: + - docker.service + - containerd.service diff --git a/ci/ansible/roles/docker-ce/tasks/remove_old_docker_el7.yaml b/ci/ansible/roles/docker-ce/tasks/remove_old_docker_el7.yaml new file mode 100644 index 00000000..db9e0960 --- /dev/null +++ b/ci/ansible/roles/docker-ce/tasks/remove_old_docker_el7.yaml @@ -0,0 +1,15 @@ +--- +# Remove older versions of Docker +- name: Uninstall older versions of Docker + ansible.builtin.yum: + name: + - docker + - docker-client + - docker-client-latest + - docker-common + - docker-latest + - docker-latest-logrotate + - docker-logrotate + - docker-engine + autoremove: yes + state: absent diff --git a/ci/ansible/roles/docker-ce/tasks/remove_old_docker_el8.yaml b/ci/ansible/roles/docker-ce/tasks/remove_old_docker_el8.yaml new file mode 100644 index 00000000..88f860cf --- /dev/null +++ b/ci/ansible/roles/docker-ce/tasks/remove_old_docker_el8.yaml @@ -0,0 +1,15 @@ +--- +# Remove older versions of Docker +- name: Uninstall older versions of Docker + ansible.builtin.dnf: + name: + - docker + - docker-client + - docker-client-latest + - docker-common + - docker-latest + - docker-latest-logrotate + - docker-logrotate + - docker-engine + autoremove: yes + state: absent diff --git a/ci/ansible/roles/docker-ce/tests/inventory b/ci/ansible/roles/docker-ce/tests/inventory new file mode 100644 index 00000000..878877b0 --- /dev/null +++ b/ci/ansible/roles/docker-ce/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/ci/ansible/roles/docker-ce/tests/test.yaml b/ci/ansible/roles/docker-ce/tests/test.yaml new file mode 100644 index 00000000..789ba96e --- /dev/null +++ b/ci/ansible/roles/docker-ce/tests/test.yaml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - docker-ce diff --git a/ci/ansible/roles/docker-ce/vars/main.yaml b/ci/ansible/roles/docker-ce/vars/main.yaml new file mode 100644 index 00000000..7ff8a18f --- /dev/null +++ b/ci/ansible/roles/docker-ce/vars/main.yaml @@ -0,0 +1,2 @@ +--- +# vars file for docker-ce diff --git a/ci/ansible/roles/minimal/README.md b/ci/ansible/roles/minimal/README.md new file mode 100644 index 00000000..225dd44b --- /dev/null +++ b/ci/ansible/roles/minimal/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/ci/ansible/roles/minimal/defaults/main.yaml b/ci/ansible/roles/minimal/defaults/main.yaml new file mode 100644 index 00000000..4a5a46cd --- /dev/null +++ b/ci/ansible/roles/minimal/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +# defaults file for minimal diff --git a/ci/ansible/roles/minimal/handlers/main.yaml b/ci/ansible/roles/minimal/handlers/main.yaml new file mode 100644 index 00000000..89105fec --- /dev/null +++ b/ci/ansible/roles/minimal/handlers/main.yaml @@ -0,0 +1,2 @@ +--- +# handlers file for minimal diff --git a/ci/ansible/roles/minimal/meta/main.yaml b/ci/ansible/roles/minimal/meta/main.yaml new file mode 100644 index 00000000..ecc81ab7 --- /dev/null +++ b/ci/ansible/roles/minimal/meta/main.yaml @@ -0,0 +1,23 @@ +galaxy_info: + author: AlmaLinux OS Community + description: Minimal configuration for ELevate + company: AlmaLinux OS Foundation + + license: GPL-3.0-or-later + + min_ansible_version: 2.11 + + platforms: + - name: EL + versions: + - 7 + - 8 + - 9 + + galaxy_tags: + - elevate + - upgrade + - cleanup + - el7 + - el8 + - el9 diff --git a/ci/ansible/roles/minimal/tasks/cleanup_el7.yaml b/ci/ansible/roles/minimal/tasks/cleanup_el7.yaml new file mode 100644 index 00000000..1b4af7c6 --- /dev/null +++ b/ci/ansible/roles/minimal/tasks/cleanup_el7.yaml @@ -0,0 +1,10 @@ +--- +# Remove old kernels +- name: Install the yum-utils + ansible.builtin.yum: + name: yum-utils + state: present + update_cache: yes + +- name: Remove the old kernels on EL7 + ansible.builtin.command: package-cleanup -y --oldkernels --count=1 diff --git a/ci/ansible/roles/minimal/tasks/cleanup_el8.yaml b/ci/ansible/roles/minimal/tasks/cleanup_el8.yaml new file mode 100644 index 00000000..56aeefd3 --- /dev/null +++ b/ci/ansible/roles/minimal/tasks/cleanup_el8.yaml @@ -0,0 +1,7 @@ +--- +# Remove old kernels +- name: Remove old kernels on EL8 + ansible.builtin.command: dnf -y remove --oldinstallonly + register: removeoldkernels + changed_when: removeoldkernels.rc == 0 + failed_when: removeoldkernels.rc > 1 diff --git a/ci/ansible/roles/minimal/tasks/main.yaml b/ci/ansible/roles/minimal/tasks/main.yaml new file mode 100644 index 00000000..8c1b35bd --- /dev/null +++ b/ci/ansible/roles/minimal/tasks/main.yaml @@ -0,0 +1,21 @@ +--- +# tasks file for minimal +- name: Upgrade the packages on EL7 + ansible.builtin.include_tasks: upgrade_el7.yaml + when: ansible_facts['distribution_major_version'] == '7' + +- name: Upgrade the packages on EL8 + ansible.builtin.include_tasks: upgrade_el8.yaml + when: ansible_facts['distribution_major_version'] == '8' + +- name: Reboot the system + ansible.builtin.reboot: + when: upgrade_status is changed + +- name: Cleanup the older kernels on EL7 + ansible.builtin.include_tasks: cleanup_el7.yaml + when: ansible_facts['distribution_major_version'] == '7' + +- name: Cleanup the older kernels on El8 + ansible.builtin.include_tasks: cleanup_el8.yaml + when: ansible_facts['distribution_major_version'] == '8' diff --git a/ci/ansible/roles/minimal/tasks/upgrade_el7.yaml b/ci/ansible/roles/minimal/tasks/upgrade_el7.yaml new file mode 100644 index 00000000..7648a586 --- /dev/null +++ b/ci/ansible/roles/minimal/tasks/upgrade_el7.yaml @@ -0,0 +1,8 @@ +--- +# Upgrade the system +- name: Upgrade the system + ansible.builtin.yum: + name: "*" + state: latest + update_cache: yes + register: upgrade_status diff --git a/ci/ansible/roles/minimal/tasks/upgrade_el8.yaml b/ci/ansible/roles/minimal/tasks/upgrade_el8.yaml new file mode 100644 index 00000000..0d4a5d2a --- /dev/null +++ b/ci/ansible/roles/minimal/tasks/upgrade_el8.yaml @@ -0,0 +1,8 @@ +--- +# Upgrade the system +- name: Upgrade the system + ansible.builtin.dnf: + name: "*" + state: latest + update_cache: yes + register: upgrade_status diff --git a/ci/ansible/roles/minimal/tests/inventory b/ci/ansible/roles/minimal/tests/inventory new file mode 100644 index 00000000..878877b0 --- /dev/null +++ b/ci/ansible/roles/minimal/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/ci/ansible/roles/minimal/tests/test.yaml b/ci/ansible/roles/minimal/tests/test.yaml new file mode 100644 index 00000000..db5c4c17 --- /dev/null +++ b/ci/ansible/roles/minimal/tests/test.yaml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - minimal diff --git a/ci/ansible/roles/minimal/vars/main.yaml b/ci/ansible/roles/minimal/vars/main.yaml new file mode 100644 index 00000000..b24df080 --- /dev/null +++ b/ci/ansible/roles/minimal/vars/main.yaml @@ -0,0 +1,2 @@ +--- +# vars file for minimal diff --git a/ci/jenkins/ELevate_el7toel8_Development.jenkinsfile b/ci/jenkins/ELevate_el7toel8_Development.jenkinsfile new file mode 100644 index 00000000..317209ef --- /dev/null +++ b/ci/jenkins/ELevate_el7toel8_Development.jenkinsfile @@ -0,0 +1,249 @@ +RETRY = params.RETRY +TIMEOUT = params.TIMEOUT + +pipeline { + agent { + label 'x86_64 && bm' + } + options { + timestamps() + parallelsAlwaysFailFast() + } + parameters { + choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8', 'all'], description: 'Select a target distro or all for ELevation') + choice(name: 'CONF_FILTER', choices: ['minimal', 'docker-ce'], description: 'Select a configuration') + string(name: 'LEAPP_SRC_GIT_USER', defaultValue: 'AlmaLinux', description: 'Input name of Git user of LEAPP source', trim: true) + string(name: 'LEAPP_SRC_GIT_BRANCH', defaultValue: 'almalinux', description: 'Input name of Git branch of LEAPP source', trim: true) + string(name: 'RETRY', defaultValue: '3', description: 'Input count of retry', trim: true) + string(name: 'TIMEOUT', defaultValue: '60', description: 'Input timeout value in minutes', trim: true) + } + environment { + VAGRANT_NO_COLOR = '1' + } + stages { + stage('Prepare') { + steps { + sh script: 'ansible-galaxy install -r ci/ansible/requirements.yaml', + label: 'Install Ansible collections' + sh script: 'python3.11 -m venv .venv', + label: 'Create Python virtual environment' + sh script: '. .venv/bin/activate && pip install --no-color pip pytest-testinfra paramiko', + label: 'Install Testinfra' + sh script: 'git clone https://github.com/AlmaLinux/leapp-data.git --branch devel', + label: 'Fetch devel version of leapp data' + } + } + stage('CreateSingleMachine') { + when { + expression { params.TARGET_DISTRO_FILTER != 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO_FILTER) + + sh script: 'cp ci/vagrant/el7toel8toel9_single.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: "vagrant up $targetDistro.vmName", + label: 'Create source VM' + } + } + } + stage('CreateMultiMachine') { + when { + expression { params.TARGET_DISTRO_FILTER == 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + sh script: 'cp ci/vagrant/el7toel8_multi.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: 'vagrant up', + label: 'Create source VM' + } + } + stage('ELevationAndTest') { + matrix { + when { + anyOf { + expression { params.TARGET_DISTRO_FILTER == 'all' } + expression { params.TARGET_DISTRO_FILTER == env.TARGET_DISTRO } + } + } + axes { + axis { + name 'TARGET_DISTRO' + values 'almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8' + } + } + stages { + stage('ELevate') { + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum-config-manager --add-repo https://repo.almalinux.org/elevate/testing/elevate-testing.repo\"", + label: 'Add testing repo of ELevate' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum install -y leapp-upgrade\"", + label: 'Install testing version of ELevate' + sh script: "vagrant upload ci/scripts/install_elevate_dev.sh install_elevate_dev.sh $targetDistro.vmName", + label: 'Upload installer script to VMs' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo bash install_elevate_dev.sh -u ${LEAPP_SRC_GIT_USER} -b ${LEAPP_SRC_GIT_BRANCH}\"", + label: 'Install development version of ELevate', + returnStatus: true + sh script: "vagrant upload leapp-data/ leapp-data/ --compress $targetDistro.vmName", + label: 'Upload devel branch of leapp data' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo mkdir -p /etc/leapp/files/vendors.d\"", + label: 'Create directory structrue of leapp data' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo install -t /etc/leapp/files leapp-data/files/${targetDistro.leappData}/*\"", + label: 'Install devel version of leapp data' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo install -t /etc/leapp/files/vendors.d leapp-data/vendors.d/*\"", + label: 'Install devel version of leapp vendor data' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo mv -f /etc/leapp/files/leapp_upgrade_repositories.repo.el8 /etc/leapp/files/leapp_upgrade_repositories.repo\"", + label: 'Configure leapp upgrade repositories for EL7toEL8' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo mv -f /etc/leapp/files/repomap.json.el8 /etc/leapp/files/repomap.json\"", + label: 'Configure leapp repository mapping for EL7toEL8' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum -y install tree && sudo tree -ha /etc/leapp\"", + label: 'Check if development version of leapp data installed correctly' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp preupgrade\"", + label: 'Start pre-upgrade check', + returnStatus: true + sh script: "vagrant ssh $targetDistro.vmName -c \"echo PermitRootLogin yes | sudo tee -a /etc/ssh/sshd_config\"", + label: 'Permit ssh as root login' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp answer --section remove_pam_pkcs11_module_check.confirm=True\"", + label: 'Answer the leapp question' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp upgrade\"", + label: 'Start the Upgrade' + sh script: "vagrant reload $targetDistro.vmName", + label: 'Reboot to the ELevate initramfs' + sh script: "vagrant ssh-config $targetDistro.vmName >> .vagrant/ssh-config", + label: 'Generate the ssh-config file' + } + } + } + } + } + stage('Distro Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'minimal' } + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: 'rm -f conftest.py pytest.ini', + label: 'Delete root conftest.py file' + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}.py + """, + label: 'Run the distro specific tests' + } + } + } + } + } + stage('Docker Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/docker/test_docker_ce_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/docker/test_docker_ce.py + """, + label: 'Run the docker specific tests' + } + } + } + } + } + } + } + } + } + post { + success { + junit testResults: 'ci/tests/tests/**/**_junit.xml', + skipPublishingChecks: true + } + cleanup { + sh script: 'vagrant destroy -f --no-parallel -g', + label: 'Destroy VMs' + cleanWs() + } + } +} + +def targetDistroSpec(distro) { + def spec = [:] + + switch (distro) { + case 'almalinux-8': + vm = 'almalinux_8' + ldata = 'almalinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'centos-stream-8': + vm = 'centosstream_8' + ldata = 'centos' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'oraclelinux-8': + vm = 'oraclelinux_8' + ldata = 'oraclelinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'rocky-8': + vm = 'rocky_8' + ldata = 'rocky' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + default: + spec = [ + vmName: 'unknown', + leappData: 'unknown' + ] + break + } + return spec +} diff --git a/ci/jenkins/ELevate_el7toel8_Internal.jenkinsfile b/ci/jenkins/ELevate_el7toel8_Internal.jenkinsfile new file mode 100644 index 00000000..97f900fe --- /dev/null +++ b/ci/jenkins/ELevate_el7toel8_Internal.jenkinsfile @@ -0,0 +1,230 @@ +RETRY = params.RETRY +TIMEOUT = params.TIMEOUT + +pipeline { + agent { + label 'x86_64 && bm' + } + options { + timestamps() + parallelsAlwaysFailFast() + } + parameters { + choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8', 'all'], description: 'Select a target distro or all for ELevation') + choice(name: 'CONF_FILTER', choices: ['minimal', 'docker-ce'], description: 'Select a configuration') + string(name: 'RETRY', defaultValue: '3', description: 'Input count of retry', trim: true) + string(name: 'TIMEOUT', defaultValue: '60', description: 'Input timeout value in minutes', trim: true) + } + environment { + VAGRANT_NO_COLOR = '1' + } + stages { + stage('Prepare') { + steps { + sh script: 'ansible-galaxy install -r ci/ansible/requirements.yaml', + label: 'Install Ansible collections' + sh script: 'python3.11 -m venv .venv', + label: 'Create Python virtual environment' + sh script: '. .venv/bin/activate && pip install --no-color pip pytest-testinfra paramiko', + label: 'Install Testinfra' + } + } + stage('CreateSingleMachine') { + when { + expression { params.TARGET_DISTRO_FILTER != 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO_FILTER) + + sh script: 'cp ci/vagrant/el7toel8toel9_single.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: "vagrant up $targetDistro.vmName", + label: 'Create source VM' + } + } + } + stage('CreateMultiMachine') { + when { + expression { params.TARGET_DISTRO_FILTER == 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + sh script: 'cp ci/vagrant/el7toel8_multi.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: 'vagrant up', + label: 'Create source VM' + } + } + stage('ELevationAndTest') { + matrix { + when { + anyOf { + expression { params.TARGET_DISTRO_FILTER == 'all' } + expression { params.TARGET_DISTRO_FILTER == env.TARGET_DISTRO } + } + } + axes { + axis { + name 'TARGET_DISTRO' + values 'almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8' + } + } + stages { + stage('ELevate') { + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum install -y https://repo.almalinux.org/elevate/elevate-release-latest-el7.noarch.rpm\"", + label: 'Install the elevate-release-latest rpm packages for EL7' + sh script: "vagrant ssh $targetDistro.vmName -c \"wget https://build.almalinux.org/pulp/content/copr/eabdullin1-leapp-data-internal-almalinux-8-x86_64-dr/config.repo -O /etc/yum.repos.d/internal-leapp.repo\"", + label: 'Add pulp repository' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum install -y leapp-upgrade\"", + label: 'Install the leap rpm package' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum install -y $targetDistro.leappData\"", + label: 'Install the LEAP migration data rpm packages' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp preupgrade\"", + label: 'Start the Pre-Upgrade check', + returnStatus: true + sh script: "vagrant ssh $targetDistro.vmName -c \"echo PermitRootLogin yes | sudo tee -a /etc/ssh/sshd_config\"", + label: 'Permit ssh as root login' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp answer --section remove_pam_pkcs11_module_check.confirm=True\"", + label: 'Answer the LEAP question' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp upgrade\"", + label: 'Start the Upgrade' + sh script: "vagrant reload $targetDistro.vmName", + label: 'Reboot to the ELevate initramfs' + sh script: "vagrant ssh-config $targetDistro.vmName >> .vagrant/ssh-config", + label: 'Generate the ssh-config file' + } + } + } + } + } + stage('Distro Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'minimal' } + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: 'rm -f conftest.py pytest.ini', + label: 'Delete root conftest.py file' + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}.py + """, + label: 'Run the distro specific tests' + } + } + } + } + } + stage('Docker Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/docker/test_docker_ce_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/docker/test_docker_ce.py + """, + label: 'Run the docker specific tests' + } + } + } + } + } + } + } + } + } + post { + success { + junit testResults: 'ci/tests/tests/**/**_junit.xml', + skipPublishingChecks: true + } + cleanup { + sh script: 'vagrant destroy -f --no-parallel -g', + label: 'Destroy VMs' + cleanWs() + } + } +} + +def targetDistroSpec(distro) { + def spec = [:] + + switch (distro) { + case 'almalinux-8': + vm = 'almalinux_8' + ldata = 'leapp-data-almalinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'centos-stream-8': + vm = 'centosstream_8' + ldata = 'leapp-data-centos' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'oraclelinux-8': + vm = 'oraclelinux_8' + ldata = 'leapp-data-oraclelinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'rocky-8': + vm = 'rocky_8' + ldata = 'leapp-data-rocky' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + default: + spec = [ + vmName: 'unknown', + leappData: 'unknown' + ] + break + } + return spec +} diff --git a/ci/jenkins/ELevate_el7toel8_Internal_Dev.jenkinsfile b/ci/jenkins/ELevate_el7toel8_Internal_Dev.jenkinsfile new file mode 100644 index 00000000..af2fabe2 --- /dev/null +++ b/ci/jenkins/ELevate_el7toel8_Internal_Dev.jenkinsfile @@ -0,0 +1,253 @@ +RETRY = params.RETRY +TIMEOUT = params.TIMEOUT + +pipeline { + agent { + label 'x86_64 && bm' + } + options { + timestamps() + parallelsAlwaysFailFast() + } + parameters { + choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8', 'all'], description: 'Select a target distro or all for ELevation') + choice(name: 'CONF_FILTER', choices: ['minimal', 'docker-ce'], description: 'Select a configuration') + string(name: 'LEAPP_SRC_GIT_USER', defaultValue: 'AlmaLinux', description: 'Input name of Git user of LEAPP source', trim: true) + string(name: 'LEAPP_SRC_GIT_BRANCH', defaultValue: 'almalinux', description: 'Input name of Git branch of LEAPP source', trim: true) + string(name: 'RETRY', defaultValue: '3', description: 'Input count of retry', trim: true) + string(name: 'TIMEOUT', defaultValue: '60', description: 'Input timeout value in minutes', trim: true) + } + environment { + VAGRANT_NO_COLOR = '1' + } + stages { + stage('Prepare') { + steps { + sh script: 'ansible-galaxy install -r ci/ansible/requirements.yaml', + label: 'Install Ansible collections' + sh script: 'python3.11 -m venv .venv', + label: 'Create Python virtual environment' + sh script: '. .venv/bin/activate && pip install --no-color pip pytest-testinfra paramiko', + label: 'Install Testinfra' + sh script: 'git clone https://github.com/AlmaLinux/leapp-data.git --branch devel', + label: 'Fetch devel version of leapp data' + } + } + stage('CreateSingleMachine') { + when { + expression { params.TARGET_DISTRO_FILTER != 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO_FILTER) + + sh script: 'cp ci/vagrant/el7toel8toel9_single.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: "vagrant up $targetDistro.vmName", + label: 'Create source VM' + } + } + } + stage('CreateMultiMachine') { + when { + expression { params.TARGET_DISTRO_FILTER == 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + sh script: 'cp ci/vagrant/el7toel8_multi.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: 'vagrant up', + label: 'Create source VM' + } + } + stage('ELevationAndTest') { + matrix { + when { + anyOf { + expression { params.TARGET_DISTRO_FILTER == 'all' } + expression { params.TARGET_DISTRO_FILTER == env.TARGET_DISTRO } + } + } + axes { + axis { + name 'TARGET_DISTRO' + values 'almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8' + } + } + stages { + stage('ELevate') { + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum-config-manager --add-repo https://repo.almalinux.org/elevate/testing/elevate-testing.repo\"", + label: 'Add testing repo of ELevate' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo wget https://build.almalinux.org/pulp/content/copr/eabdullin1-leapp-data-internal-centos7-x86_64-dr/config.repo -O /etc/yum.repos.d/internal-leapp.repo\"", + label: 'Add pulp repository' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo sed -i 's|enabled=1|enabled=1\\npriority=80|' /etc/yum.repos.d/internal-leapp.repo\"", + label: 'Set priority for pulp repository' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum install -y leapp-upgrade\"", + label: 'Install testing version of ELevate' + sh script: "vagrant upload ci/scripts/install_elevate_dev.sh install_elevate_dev.sh $targetDistro.vmName", + label: 'Upload installer script to VMs' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo bash install_elevate_dev.sh -u ${LEAPP_SRC_GIT_USER} -b ${LEAPP_SRC_GIT_BRANCH}\"", + label: 'Install development version of ELevate', + returnStatus: true + sh script: "vagrant upload leapp-data/ leapp-data/ --compress $targetDistro.vmName", + label: 'Upload devel branch of leapp data' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo mkdir -p /etc/leapp/files/vendors.d\"", + label: 'Create directory structrue of leapp data' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo install -t /etc/leapp/files leapp-data/files/${targetDistro.leappData}/*\"", + label: 'Install devel version of leapp data' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo install -t /etc/leapp/files/vendors.d leapp-data/vendors.d/*\"", + label: 'Install devel version of leapp vendor data' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo mv -f /etc/leapp/files/leapp_upgrade_repositories.repo.el8 /etc/leapp/files/leapp_upgrade_repositories.repo\"", + label: 'Configure leapp upgrade repositories for EL7toEL8' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo mv -f /etc/leapp/files/repomap.json.el8 /etc/leapp/files/repomap.json\"", + label: 'Configure leapp repository mapping for EL7toEL8' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum -y install tree && sudo tree -ha /etc/leapp\"", + label: 'Check if development version of leapp data installed correctly' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp preupgrade\"", + label: 'Start pre-upgrade check', + returnStatus: true + sh script: "vagrant ssh $targetDistro.vmName -c \"echo PermitRootLogin yes | sudo tee -a /etc/ssh/sshd_config\"", + label: 'Permit ssh as root login' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp answer --section remove_pam_pkcs11_module_check.confirm=True\"", + label: 'Answer the leapp question' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp upgrade\"", + label: 'Start the Upgrade' + sh script: "vagrant reload $targetDistro.vmName", + label: 'Reboot to the ELevate initramfs' + sh script: "vagrant ssh-config $targetDistro.vmName >> .vagrant/ssh-config", + label: 'Generate the ssh-config file' + } + } + } + } + } + stage('Distro Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'minimal' } + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: 'rm -f conftest.py pytest.ini', + label: 'Delete root conftest.py file' + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}.py + """, + label: 'Run the distro specific tests' + } + } + } + } + } + stage('Docker Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/docker/test_docker_ce_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/docker/test_docker_ce.py + """, + label: 'Run the docker specific tests' + } + } + } + } + } + } + } + } + } + post { + success { + junit testResults: 'ci/tests/tests/**/**_junit.xml', + skipPublishingChecks: true + } + cleanup { + sh script: 'vagrant destroy -f --no-parallel -g', + label: 'Destroy VMs' + cleanWs() + } + } +} + +def targetDistroSpec(distro) { + def spec = [:] + + switch (distro) { + case 'almalinux-8': + vm = 'almalinux_8' + ldata = 'almalinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'centos-stream-8': + vm = 'centosstream_8' + ldata = 'centos' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'oraclelinux-8': + vm = 'oraclelinux_8' + ldata = 'oraclelinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'rocky-8': + vm = 'rocky_8' + ldata = 'rocky' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + default: + spec = [ + vmName: 'unknown', + leappData: 'unknown' + ] + break + } + return spec +} diff --git a/ci/jenkins/ELevate_el7toel8_Stable.jenkinsfile b/ci/jenkins/ELevate_el7toel8_Stable.jenkinsfile new file mode 100644 index 00000000..ae9bdb57 --- /dev/null +++ b/ci/jenkins/ELevate_el7toel8_Stable.jenkinsfile @@ -0,0 +1,228 @@ +RETRY = params.RETRY +TIMEOUT = params.TIMEOUT + +pipeline { + agent { + label 'x86_64 && bm' + } + options { + timestamps() + parallelsAlwaysFailFast() + } + parameters { + choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8', 'all'], description: 'Select a target distro or all for ELevation') + choice(name: 'CONF_FILTER', choices: ['minimal', 'docker-ce'], description: 'Select a configuration') + string(name: 'RETRY', defaultValue: '3', description: 'Input count of retry', trim: true) + string(name: 'TIMEOUT', defaultValue: '60', description: 'Input timeout value in minutes', trim: true) + } + environment { + VAGRANT_NO_COLOR = '1' + } + stages { + stage('Prepare') { + steps { + sh script: 'ansible-galaxy install -r ci/ansible/requirements.yaml', + label: 'Install Ansible collections' + sh script: 'python3.11 -m venv .venv', + label: 'Create Python virtual environment' + sh script: '. .venv/bin/activate && pip install --no-color pip pytest-testinfra paramiko', + label: 'Install Testinfra' + } + } + stage('CreateSingleMachine') { + when { + expression { params.TARGET_DISTRO_FILTER != 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO_FILTER) + + sh script: 'cp ci/vagrant/el7toel8toel9_single.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: "vagrant up $targetDistro.vmName", + label: 'Create source VM' + } + } + } + stage('CreateMultiMachine') { + when { + expression { params.TARGET_DISTRO_FILTER == 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + sh script: 'cp ci/vagrant/el7toel8_multi.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: 'vagrant up', + label: 'Create source VM' + } + } + stage('ELevationAndTest') { + matrix { + when { + anyOf { + expression { params.TARGET_DISTRO_FILTER == 'all' } + expression { params.TARGET_DISTRO_FILTER == env.TARGET_DISTRO } + } + } + axes { + axis { + name 'TARGET_DISTRO' + values 'almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8' + } + } + stages { + stage('ELevate') { + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum install -y https://repo.almalinux.org/elevate/elevate-release-latest-el7.noarch.rpm\"", + label: 'Install the elevate-release-latest rpm packages for EL7' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum install -y leapp-upgrade\"", + label: 'Install the leap rpm package' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum install -y $targetDistro.leappData\"", + label: 'Install the LEAP migration data rpm packages' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp preupgrade\"", + label: 'Start the Pre-Upgrade check', + returnStatus: true + sh script: "vagrant ssh $targetDistro.vmName -c \"echo PermitRootLogin yes | sudo tee -a /etc/ssh/sshd_config\"", + label: 'Permit ssh as root login' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp answer --section remove_pam_pkcs11_module_check.confirm=True\"", + label: 'Answer the LEAP question' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp upgrade\"", + label: 'Start the Upgrade' + sh script: "vagrant reload $targetDistro.vmName", + label: 'Reboot to the ELevate initramfs' + sh script: "vagrant ssh-config $targetDistro.vmName >> .vagrant/ssh-config", + label: 'Generate the ssh-config file' + } + } + } + } + } + stage('Distro Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'minimal' } + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: 'rm -f conftest.py pytest.ini', + label: 'Delete root conftest.py file' + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}.py + """, + label: 'Run the distro specific tests' + } + } + } + } + } + stage('Docker Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/docker/test_docker_ce_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/docker/test_docker_ce.py + """, + label: 'Run the docker specific tests' + } + } + } + } + } + } + } + } + } + post { + success { + junit testResults: 'ci/tests/tests/**/**_junit.xml', + skipPublishingChecks: true + } + cleanup { + sh script: 'vagrant destroy -f --no-parallel -g', + label: 'Destroy VMs' + cleanWs() + } + } +} + +def targetDistroSpec(distro) { + def spec = [:] + + switch (distro) { + case 'almalinux-8': + vm = 'almalinux_8' + ldata = 'leapp-data-almalinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'centos-stream-8': + vm = 'centosstream_8' + ldata = 'leapp-data-centos' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'oraclelinux-8': + vm = 'oraclelinux_8' + ldata = 'leapp-data-oraclelinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'rocky-8': + vm = 'rocky_8' + ldata = 'leapp-data-rocky' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + default: + spec = [ + vmName: 'unknown', + leappData: 'unknown' + ] + break + } + return spec +} diff --git a/ci/jenkins/ELevate_el7toel8_Testing.jenkinsfile b/ci/jenkins/ELevate_el7toel8_Testing.jenkinsfile new file mode 100644 index 00000000..0f37cf2e --- /dev/null +++ b/ci/jenkins/ELevate_el7toel8_Testing.jenkinsfile @@ -0,0 +1,228 @@ +RETRY = params.RETRY +TIMEOUT = params.TIMEOUT + +pipeline { + agent { + label 'x86_64 && bm' + } + options { + timestamps() + parallelsAlwaysFailFast() + } + parameters { + choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8', 'all'], description: 'Select a target distro or all for ELevation') + choice(name: 'CONF_FILTER', choices: ['minimal', 'docker-ce'], description: 'Select a configuration') + string(name: 'RETRY', defaultValue: '3', description: 'Input count of retry', trim: true) + string(name: 'TIMEOUT', defaultValue: '60', description: 'Input timeout value in minutes', trim: true) + } + environment { + VAGRANT_NO_COLOR = '1' + } + stages { + stage('Prepare') { + steps { + sh script: 'ansible-galaxy install -r ci/ansible/requirements.yaml', + label: 'Install Ansible collections' + sh script: 'python3.11 -m venv .venv', + label: 'Create Python virtual environment' + sh script: '. .venv/bin/activate && pip install --no-color pip pytest-testinfra paramiko', + label: 'Install Testinfra' + } + } + stage('CreateSingleMachine') { + when { + expression { params.TARGET_DISTRO_FILTER != 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO_FILTER) + + sh script: 'cp ci/vagrant/el7toel8toel9_single.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: "vagrant up $targetDistro.vmName", + label: 'Create source VM' + } + } + } + stage('CreateMultiMachine') { + when { + expression { params.TARGET_DISTRO_FILTER == 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + sh script: 'cp ci/vagrant/el7toel8_multi.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: 'vagrant up', + label: 'Create source VM' + } + } + stage('ELevationAndTest') { + matrix { + when { + anyOf { + expression { params.TARGET_DISTRO_FILTER == 'all' } + expression { params.TARGET_DISTRO_FILTER == env.TARGET_DISTRO } + } + } + axes { + axis { + name 'TARGET_DISTRO' + values 'almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8' + } + } + stages { + stage('ELevate') { + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum-config-manager --add-repo https://repo.almalinux.org/elevate/testing/elevate-testing.repo\"", + label: 'Install the elevate-release-latest rpm packages for EL7' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum install -y leapp-upgrade\"", + label: 'Install the leap rpm package' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo yum install -y $targetDistro.leappData\"", + label: 'Install the LEAP migration data rpm packages' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp preupgrade\"", + label: 'Start the Pre-Upgrade check', + returnStatus: true + sh script: "vagrant ssh $targetDistro.vmName -c \"echo PermitRootLogin yes | sudo tee -a /etc/ssh/sshd_config\"", + label: 'Permit ssh as root login' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp answer --section remove_pam_pkcs11_module_check.confirm=True\"", + label: 'Answer the LEAP question' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp upgrade\"", + label: 'Start the Upgrade' + sh script: "vagrant reload $targetDistro.vmName", + label: 'Reboot to the ELevate initramfs' + sh script: "vagrant ssh-config $targetDistro.vmName >> .vagrant/ssh-config", + label: 'Generate the ssh-config file' + } + } + } + } + } + stage('Distro Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'minimal' } + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: 'rm -f conftest.py pytest.ini', + label: 'Delete root conftest.py file' + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}.py + """, + label: 'Run the distro specific tests' + } + } + } + } + } + stage('Docker Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/docker/test_docker_ce_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/docker/test_docker_ce.py + """, + label: 'Run the docker specific tests' + } + } + } + } + } + } + } + } + } + post { + success { + junit testResults: 'ci/tests/tests/**/**_junit.xml', + skipPublishingChecks: true + } + cleanup { + sh script: 'vagrant destroy -f --no-parallel -g', + label: 'Destroy VMs' + cleanWs() + } + } +} + +def targetDistroSpec(distro) { + def spec = [:] + + switch (distro) { + case 'almalinux-8': + vm = 'almalinux_8' + ldata = 'leapp-data-almalinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'centos-stream-8': + vm = 'centosstream_8' + ldata = 'leapp-data-centos' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'oraclelinux-8': + vm = 'oraclelinux_8' + ldata = 'leapp-data-oraclelinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'rocky-8': + vm = 'rocky_8' + ldata = 'leapp-data-rocky' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + default: + spec = [ + vmName: 'unknown', + leappData: 'unknown' + ] + break + } + return spec +} diff --git a/ci/jenkins/ELevate_el8toel9_Development.jenkinsfile b/ci/jenkins/ELevate_el8toel9_Development.jenkinsfile new file mode 100644 index 00000000..7eb5430b --- /dev/null +++ b/ci/jenkins/ELevate_el8toel9_Development.jenkinsfile @@ -0,0 +1,200 @@ +RETRY = params.RETRY +TIMEOUT = params.TIMEOUT + +pipeline { + agent { + label params.AGENT + } + options { + timestamps() + } + parameters { + string(name: 'AGENT', defaultValue: 'almalinux-8-vagrant-libvirt-x86_64', description: 'Input label of the Jenkins Agent', trim: true) + string(name: 'RETRY', defaultValue: '3', description: 'Input count of retry', trim: true) + string(name: 'TIMEOUT', defaultValue: '60', description: 'Input timeout value in minutes', trim: true) + string(name: 'REPO_URL', defaultValue: 'https://github.com/LKHN/el-test-auto-dev.git', description: 'URL of the pipeline repository', trim: true) + string(name: 'REPO_BRANCH', defaultValue: 'main', description: 'Branch of the pipeline repository', trim: true) + choice(name: 'SOURCE_DISTRO_FILTER', choices: ['almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8', 'all'], description: 'Select a source distro or all for ELevation') + choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-9', 'centos-stream-9', 'oraclelinux-9', 'rocky-9', 'all'], description: 'Select a target distro or all to ELevation') + choice(name: 'CONF_FILTER', choices: ['minimal', 'docker-ce'], description: 'Select a configuration') + } + stages { + stage('Source') { + steps { + git url: REPO_URL, + branch: REPO_BRANCH, + credentialsId: 'github-almalinuxautobot' + } + } + stage('Prepare Build and Test enviroment') { + steps { + sh script: 'cp Vagrantfile.el8toel9 Vagrantfile', + label: 'Generate the el8toel9 Vagrantfile' + sh script: 'sudo dnf -y install python39-devel python39-wheel', + label: 'Install Python 3.9, PIP and Wheel' + sh script: 'sudo python3 -m pip install --no-cache-dir --upgrade -r requirements.txt', + label: 'Install TestInfra' + sh script: 'git clone https://github.com/AlmaLinux/leapp-data.git --branch devel', + label: 'Clone the leapp-data git repository' + } + } + stage('ELevation') { + matrix { + when { + allOf { + anyOf { + expression { params.SOURCE_DISTRO_FILTER == 'all' } + expression { params.SOURCE_DISTRO_FILTER == env.SOURCE_DISTRO } + } + anyOf { + expression { params.TARGET_DISTRO_FILTER == 'all' } + expression { params.TARGET_DISTRO_FILTER == env.TARGET_DISTRO } + } + } + } + axes { + axis { + name 'SOURCE_DISTRO' + values 'almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8' + } + axis { + name 'TARGET_DISTRO' + values 'almalinux-9', 'centos-stream-9', 'oraclelinux-9', 'rocky-9' + } + } + stages { + stage('Create and Configure Machines') { + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'vagrant destroy -f $SOURCE_DISTRO', + label: 'Make sure no machine present from the last retry' + sh script: 'vagrant up $SOURCE_DISTRO', + label: 'Create the source machines' + } + } + } + } + stage('ELevate to the all target distros') { + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo dnf config-manager --add-repo https://repo.almalinux.org/elevate/testing/elevate-testing.repo\"', + label: 'Add the ELevate Testing RPM repository' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo dnf install -y leapp-upgrade\"', + label: 'Install the leap rpm package' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo bash /vagrant/scripts/install_elevate_dev.sh\"', + label: 'Install Development version of ELevate', + returnStatus: true + script { + def LEAPP_DATA = getLeappDataDistro(TARGET_DISTRO) + sh(script:"vagrant ssh $SOURCE_DISTRO -c \"sudo mkdir -p /etc/leapp/files/vendors.d\"", + label:'Create the LEAPP directory') + sh(script:"vagrant ssh $SOURCE_DISTRO -c \"sudo install -t /etc/leapp/files /vagrant/leapp-data/files/${LEAPP_DATA}/*\"", + label:"Install the LEAPP DATA") + sh(script:'vagrant ssh $SOURCE_DISTRO -c \"sudo install -t /etc/leapp/files/vendors.d /vagrant/leapp-data/vendors.d/*\"', + label:"Install the Vendor DATA") + sh(script:"vagrant ssh $SOURCE_DISTRO -c \"sudo mv -f /etc/leapp/files/leapp_upgrade_repositories.repo.el9 /etc/leapp/files/leapp_upgrade_repositories.repo\"", + label:'Set LEAPP Repos for EL8') + sh(script:"vagrant ssh $SOURCE_DISTRO -c \"sudo mv -f /etc/leapp/files/repomap.json.el9 /etc/leapp/files/repomap.json\"", + label:'Set LEAPP Repo map for EL8') + sh(script:'vagrant ssh $SOURCE_DISTRO -c \"sudo dnf -y install tree && sudo tree -ha /etc/leapp\"', + label:"Debug: Data paths") + } + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo leapp preupgrade\"', + label: 'Start the Pre-Upgrade check', + returnStatus: true + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"echo PermitRootLogin yes | sudo tee -a /etc/ssh/sshd_config\"', + label: 'Permit ssh as root login' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo leapp answer --section remove_pam_pkcs11_module_check.confirm=True\"', + label: 'Answer the LEAP question' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo leapp upgrade\"', + label: 'Start the Upgrade' + sh script: 'vagrant reload $SOURCE_DISTRO', + label: 'Reboot to the ELevate initramfs' + sh script: 'vagrant ssh-config $SOURCE_DISTRO >> .vagrant/ssh-config', + label: 'Generate the ssh-config file' + } + } + } + } + stage('Distro Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'minimal'} + expression { params.CONF_FILTER == 'docker-ce'} + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'py.test -v --hosts=$SOURCE_DISTRO --ssh-config=.vagrant/ssh-config --junit-xml tests/distro/test_osinfo_$SOURCE_DISTRO-junit.xml tests/distro/test_osinfo_$SOURCE_DISTRO.py', + label: 'Run the distro specific tests' + } + } + } + } + stage('Docker Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'docker-ce'} + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'py.test -v --hosts=$SOURCE_DISTRO --ssh-config=.vagrant/ssh-config --junit-xml tests/docker/test_docker_ce_$SOURCE_DISTRO-junit.xml tests/docker/test_docker_ce.py', + label: 'Run the distro specific tests' + } + } + } + } + } + } + } + } + post { + success { + junit testResults: '**/tests/**/**-junit.xml', + skipPublishingChecks: true + } + cleanup { + sh script: 'vagrant destroy -f', + label: 'Destroy All Machines' + cleanWs() + } + } +} + +/* +* Common Functions +*/ +def getLeappDataDistro(TARGET_DISTRO) { + def leapp_data = "" + + switch(TARGET_DISTRO) { + case "almalinux-9": + leapp_data = TARGET_DISTRO.substring(0, 9) + break + + case "centos-stream-9": + leapp_data = TARGET_DISTRO.substring(0, 6) + break + + case "oraclelinux-9": + leapp_data = TARGET_DISTRO.substring(0, 11) + break + + case "rocky-9": + leapp_data = TARGET_DISTRO.substring(0, 5) + break + + default: + leap_data = "Error: Target Distro Not Supported" + break + } + return leapp_data +} diff --git a/ci/jenkins/ELevate_el8toel9_Internal.jenkinsfile b/ci/jenkins/ELevate_el8toel9_Internal.jenkinsfile new file mode 100644 index 00000000..aa6be967 --- /dev/null +++ b/ci/jenkins/ELevate_el8toel9_Internal.jenkinsfile @@ -0,0 +1,214 @@ +RETRY = params.RETRY +TIMEOUT = params.TIMEOUT + +pipeline { + agent { + label 'x86_64 && bm' + } + options { + timestamps() + parallelsAlwaysFailFast() + } + parameters { + // choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-9', 'centos-stream-9', 'rocky-9', 'all'], description: 'Select a target distro or all for ELevation') + choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-9', 'rocky-9', 'all'], description: 'Select a target distro or all for ELevation') + choice(name: 'CONF_FILTER', choices: ['minimal', 'docker-ce'], description: 'Select a configuration') + string(name: 'RETRY', defaultValue: '3', description: 'Input count of retry', trim: true) + string(name: 'TIMEOUT', defaultValue: '60', description: 'Input timeout value in minutes', trim: true) + } + environment { + VAGRANT_NO_COLOR = '1' + } + stages { + stage('Prepare') { + steps { + sh script: 'ansible-galaxy install -r ci/ansible/requirements.yaml', + label: 'Install Ansible collections' + sh script: 'python3.11 -m venv .venv', + label: 'Create Python virtual environment' + sh script: '. .venv/bin/activate && pip install --no-color pip pytest-testinfra paramiko', + label: 'Install Testinfra' + } + } + stage('CreateSingleMachine') { + when { + expression { params.TARGET_DISTRO_FILTER != 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO_FILTER) + + sh script: 'cp ci/vagrant/el7toel8toel9_single.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: "vagrant up $targetDistro.vmName", + label: 'Create source VM' + } + } + } + stage('CreateMultiMachine') { + when { + expression { params.TARGET_DISTRO_FILTER == 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + sh script: 'cp ci/vagrant/el8toel9_multi.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: 'vagrant up', + label: 'Create source VM' + } + } + stage('ELevationAndTest') { + matrix { + when { + anyOf { + expression { params.TARGET_DISTRO_FILTER == 'all' } + expression { params.TARGET_DISTRO_FILTER == env.TARGET_DISTRO } + } + } + axes { + axis { + name 'TARGET_DISTRO' + // values 'almalinux-9', 'centos-stream-9', 'rocky-9' + values 'almalinux-9', 'rocky-9' + } + } + stages { + stage('ELevate') { + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo dnf install -y https://repo.almalinux.org/elevate/elevate-release-latest-el8.noarch.rpm\"", + label: 'Install the elevate-release-latest rpm packages for EL8' + sh script: "vagrant ssh $targetDistro.vmName -c \"wget https://build.almalinux.org/pulp/content/copr/eabdullin1-leapp-data-internal-centos7-x86_64-dr/config.repo -O /etc/yum.repos.d/internal-leapp.repo\"", + label: 'Add pulp repository' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo dnf install -y leapp-upgrade\"", + label: 'Install the leap rpm package' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo dnf install -y $targetDistro.leappData\"", + label: 'Install the LEAP migration data rpm packages' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp preupgrade\"", + label: 'Start the Pre-Upgrade check', + returnStatus: true + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo sed -i \'s/^AllowZoneDrifting=.*/AllowZoneDrifting=no/\' /etc/firewalld/firewalld.conf\"", + label: 'TODO' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp answer --section check_vdo.no_vdo_devices=True\"", + label: 'TODO' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp upgrade\"", + label: 'Start the Upgrade' + sh script: "vagrant reload $targetDistro.vmName", + label: 'Reboot to the ELevate initramfs' + sh script: "vagrant ssh-config $targetDistro.vmName >> .vagrant/ssh-config", + label: 'Generate the ssh-config file' + } + } + } + } + } + stage('Distro Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'minimal' } + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: 'rm -f conftest.py pytest.ini', + label: 'Delete root conftest.py file' + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}.py + """, + label: 'Run the distro specific tests' + } + } + } + } + } + stage('Docker Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/docker/test_docker_ce_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/docker/test_docker_ce.py + """, + label: 'Run the docker specific tests' + } + } + } + } + } + } + } + } + } + post { + success { + junit testResults: 'ci/tests/tests/**/**_junit.xml', + skipPublishingChecks: true + } + cleanup { + sh script: 'vagrant destroy -f --no-parallel -g', + label: 'Destroy VMs' + cleanWs() + } + } +} + +def targetDistroSpec(distro) { + def spec = [:] + + switch (distro) { + case 'almalinux-9': + vm = 'almalinux_9' + ldata = 'leapp-data-almalinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'rocky-9': + vm = 'rocky_9' + ldata = 'leapp-data-rocky' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + default: + spec = [ + vmName: 'unknown', + leappData: 'unknown' + ] + break + } + return spec +} diff --git a/ci/jenkins/ELevate_el8toel9_Internal_Dev.jenkinsfile b/ci/jenkins/ELevate_el8toel9_Internal_Dev.jenkinsfile new file mode 100644 index 00000000..82626697 --- /dev/null +++ b/ci/jenkins/ELevate_el8toel9_Internal_Dev.jenkinsfile @@ -0,0 +1,206 @@ +RETRY = params.RETRY +TIMEOUT = params.TIMEOUT + +pipeline { + agent { + label params.AGENT + } + options { + timestamps() + } + parameters { + string(name: 'AGENT', defaultValue: 'almalinux-8-vagrant-libvirt-x86_64', description: 'Input label of the Jenkins Agent', trim: true) + string(name: 'RETRY', defaultValue: '3', description: 'Input count of retry', trim: true) + string(name: 'TIMEOUT', defaultValue: '60', description: 'Input timeout value in minutes', trim: true) + string(name: 'REPO_URL', defaultValue: 'https://github.com/LKHN/el-test-auto-dev.git', description: 'URL of the pipeline repository', trim: true) + string(name: 'REPO_BRANCH', defaultValue: 'main', description: 'Branch of the pipeline repository', trim: true) + choice(name: 'SOURCE_DISTRO_FILTER', choices: ['almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8', 'all'], description: 'Select a source distro or all for ELevation') + choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-9', 'centos-stream-9', 'oraclelinux-9', 'rocky-9', 'all'], description: 'Select a target distro or all to ELevation') + choice(name: 'CONF_FILTER', choices: ['minimal', 'docker-ce'], description: 'Select a configuration') + } + stages { + stage('Source') { + steps { + git url: REPO_URL, + branch: REPO_BRANCH, + credentialsId: 'github-almalinuxautobot' + } + } + stage('Prepare Build and Test enviroment') { + steps { + sh script: 'cp Vagrantfile.el8toel9 Vagrantfile', + label: 'Generate the el8toel9 Vagrantfile' + sh script: 'sudo dnf -y install python39-devel python39-wheel', + label: 'Install Python 3.9, PIP and Wheel' + sh script: 'sudo python3 -m pip install --no-cache-dir --upgrade -r requirements.txt', + label: 'Install TestInfra' + sh script: 'git clone https://github.com/AlmaLinux/leapp-data.git --branch devel', + label: 'Clone the leapp-data git repository' + } + } + stage('ELevation') { + matrix { + when { + allOf { + anyOf { + expression { params.SOURCE_DISTRO_FILTER == 'all' } + expression { params.SOURCE_DISTRO_FILTER == env.SOURCE_DISTRO } + } + anyOf { + expression { params.TARGET_DISTRO_FILTER == 'all' } + expression { params.TARGET_DISTRO_FILTER == env.TARGET_DISTRO } + } + } + } + axes { + axis { + name 'SOURCE_DISTRO' + values 'almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8' + } + axis { + name 'TARGET_DISTRO' + values 'almalinux-9', 'centos-stream-9', 'oraclelinux-9', 'rocky-9' + } + } + stages { + stage('Create and Configure Machines') { + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'vagrant destroy -f $SOURCE_DISTRO', + label: 'Make sure no machine present from the last retry' + sh script: 'vagrant up $SOURCE_DISTRO', + label: 'Create the source machines' + } + } + } + } + stage('ELevate to the all target distros') { + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo dnf config-manager --add-repo https://repo.almalinux.org/elevate/testing/elevate-testing.repo\"', + label: 'Add the ELevate Testing RPM repository' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo dnf install -y wget\"", + label: 'Install wget' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo wget https://build.almalinux.org/pulp/content/copr/eabdullin1-leapp-data-internal-almalinux-8-x86_64-dr/config.repo -O /etc/yum.repos.d/internal-leapp.repo\"", + label: 'Add pulp repository' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo sed -i 's|enabled=1|enabled=1\\npriority=80|' /etc/yum.repos.d/internal-leapp.repo\"", + label: 'Set priority for pulp repository' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo dnf install -y leapp-upgrade\"', + label: 'Install the leap rpm package' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo bash /vagrant/scripts/install_elevate_dev.sh\"', + label: 'Install Development version of ELevate', + returnStatus: true + script { + def LEAPP_DATA = getLeappDataDistro(TARGET_DISTRO) + sh(script:"vagrant ssh $SOURCE_DISTRO -c \"sudo mkdir -p /etc/leapp/files/vendors.d\"", + label:'Create the LEAPP directory') + sh(script:"vagrant ssh $SOURCE_DISTRO -c \"sudo install -t /etc/leapp/files /vagrant/leapp-data/files/${LEAPP_DATA}/*\"", + label:"Install the LEAPP DATA") + sh(script:'vagrant ssh $SOURCE_DISTRO -c \"sudo install -t /etc/leapp/files/vendors.d /vagrant/leapp-data/vendors.d/*\"', + label:"Install the Vendor DATA") + sh(script:"vagrant ssh $SOURCE_DISTRO -c \"sudo mv -f /etc/leapp/files/leapp_upgrade_repositories.repo.el9 /etc/leapp/files/leapp_upgrade_repositories.repo\"", + label:'Set LEAPP Repos for EL8') + sh(script:"vagrant ssh $SOURCE_DISTRO -c \"sudo mv -f /etc/leapp/files/repomap.json.el9 /etc/leapp/files/repomap.json\"", + label:'Set LEAPP Repo map for EL8') + sh(script:'vagrant ssh $SOURCE_DISTRO -c \"sudo dnf -y install tree && sudo tree -ha /etc/leapp\"', + label:"Debug: Data paths") + } + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo leapp preupgrade\"', + label: 'Start the Pre-Upgrade check', + returnStatus: true + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"echo PermitRootLogin yes | sudo tee -a /etc/ssh/sshd_config\"', + label: 'Permit ssh as root login' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo leapp answer --section remove_pam_pkcs11_module_check.confirm=True\"', + label: 'Answer the LEAP question' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo leapp upgrade\"', + label: 'Start the Upgrade' + sh script: 'vagrant reload $SOURCE_DISTRO', + label: 'Reboot to the ELevate initramfs' + sh script: 'vagrant ssh-config $SOURCE_DISTRO >> .vagrant/ssh-config', + label: 'Generate the ssh-config file' + } + } + } + } + stage('Distro Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'minimal'} + expression { params.CONF_FILTER == 'docker-ce'} + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'py.test -v --hosts=$SOURCE_DISTRO --ssh-config=.vagrant/ssh-config --junit-xml tests/distro/test_osinfo_$SOURCE_DISTRO-junit.xml tests/distro/test_osinfo_$SOURCE_DISTRO.py', + label: 'Run the distro specific tests' + } + } + } + } + stage('Docker Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'docker-ce'} + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'py.test -v --hosts=$SOURCE_DISTRO --ssh-config=.vagrant/ssh-config --junit-xml tests/docker/test_docker_ce_$SOURCE_DISTRO-junit.xml tests/docker/test_docker_ce.py', + label: 'Run the distro specific tests' + } + } + } + } + } + } + } + } + post { + success { + junit testResults: '**/tests/**/**-junit.xml', + skipPublishingChecks: true + } + cleanup { + sh script: 'vagrant destroy -f', + label: 'Destroy All Machines' + cleanWs() + } + } +} + +/* +* Common Functions +*/ +def getLeappDataDistro(TARGET_DISTRO) { + def leapp_data = "" + + switch(TARGET_DISTRO) { + case "almalinux-9": + leapp_data = TARGET_DISTRO.substring(0, 9) + break + + case "centos-stream-9": + leapp_data = TARGET_DISTRO.substring(0, 6) + break + + case "oraclelinux-9": + leapp_data = TARGET_DISTRO.substring(0, 11) + break + + case "rocky-9": + leapp_data = TARGET_DISTRO.substring(0, 5) + break + + default: + leap_data = "Error: Target Distro Not Supported" + break + } + return leapp_data +} diff --git a/ci/jenkins/ELevate_el8toel9_Stable.jenkinsfile b/ci/jenkins/ELevate_el8toel9_Stable.jenkinsfile new file mode 100644 index 00000000..68f00165 --- /dev/null +++ b/ci/jenkins/ELevate_el8toel9_Stable.jenkinsfile @@ -0,0 +1,212 @@ +RETRY = params.RETRY +TIMEOUT = params.TIMEOUT + +pipeline { + agent { + label 'x86_64 && bm' + } + options { + timestamps() + parallelsAlwaysFailFast() + } + parameters { + // choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-9', 'centos-stream-9', 'rocky-9', 'all'], description: 'Select a target distro or all for ELevation') + choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-9', 'rocky-9', 'all'], description: 'Select a target distro or all for ELevation') + choice(name: 'CONF_FILTER', choices: ['minimal', 'docker-ce'], description: 'Select a configuration') + string(name: 'RETRY', defaultValue: '3', description: 'Input count of retry', trim: true) + string(name: 'TIMEOUT', defaultValue: '60', description: 'Input timeout value in minutes', trim: true) + } + environment { + VAGRANT_NO_COLOR = '1' + } + stages { + stage('Prepare') { + steps { + sh script: 'ansible-galaxy install -r ci/ansible/requirements.yaml', + label: 'Install Ansible collections' + sh script: 'python3.11 -m venv .venv', + label: 'Create Python virtual environment' + sh script: '. .venv/bin/activate && pip install --no-color pip pytest-testinfra paramiko', + label: 'Install Testinfra' + } + } + stage('CreateSingleMachine') { + when { + expression { params.TARGET_DISTRO_FILTER != 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO_FILTER) + + sh script: 'cp ci/vagrant/el7toel8toel9_single.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: "vagrant up $targetDistro.vmName", + label: 'Create source VM' + } + } + } + stage('CreateMultiMachine') { + when { + expression { params.TARGET_DISTRO_FILTER == 'all' } + } + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + sh script: 'cp ci/vagrant/el8toel9_multi.rb Vagrantfile', + label: 'Generate Vagrantfile' + sh script: 'vagrant up', + label: 'Create source VM' + } + } + stage('ELevationAndTest') { + matrix { + when { + anyOf { + expression { params.TARGET_DISTRO_FILTER == 'all' } + expression { params.TARGET_DISTRO_FILTER == env.TARGET_DISTRO } + } + } + axes { + axis { + name 'TARGET_DISTRO' + // values 'almalinux-9', 'centos-stream-9', 'rocky-9' + values 'almalinux-9', 'rocky-9' + } + } + stages { + stage('ELevate') { + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo dnf install -y https://repo.almalinux.org/elevate/elevate-release-latest-el8.noarch.rpm\"", + label: 'Install the elevate-release-latest rpm packages for EL8' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo dnf install -y leapp-upgrade\"", + label: 'Install the leap rpm package' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo dnf install -y $targetDistro.leappData\"", + label: 'Install the LEAP migration data rpm packages' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp preupgrade\"", + label: 'Start the Pre-Upgrade check', + returnStatus: true + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo sed -i \'s/^AllowZoneDrifting=.*/AllowZoneDrifting=no/\' /etc/firewalld/firewalld.conf\"", + label: 'TODO' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp answer --section check_vdo.no_vdo_devices=True\"", + label: 'TODO' + sh script: "vagrant ssh $targetDistro.vmName -c \"sudo leapp upgrade\"", + label: 'Start the Upgrade' + sh script: "vagrant reload $targetDistro.vmName", + label: 'Reboot to the ELevate initramfs' + sh script: "vagrant ssh-config $targetDistro.vmName >> .vagrant/ssh-config", + label: 'Generate the ssh-config file' + } + } + } + } + } + stage('Distro Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'minimal' } + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: 'rm -f conftest.py pytest.ini', + label: 'Delete root conftest.py file' + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/distro/test_osinfo_${targetDistro.vmName}.py + """, + label: 'Run the distro specific tests' + } + } + } + } + } + stage('Docker Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'docker-ce' } + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + script { + def targetDistro = targetDistroSpec(TARGET_DISTRO) + + sh script: """ + . .venv/bin/activate \ + && py.test -v --hosts=${targetDistro.vmName} \ + --ssh-config=.vagrant/ssh-config \ + --junit-xml ci/tests/tests/docker/test_docker_ce_${targetDistro.vmName}_junit.xml \ + ci/tests/tests/docker/test_docker_ce.py + """, + label: 'Run the docker specific tests' + } + } + } + } + } + } + } + } + } + post { + success { + junit testResults: 'ci/tests/tests/**/**_junit.xml', + skipPublishingChecks: true + } + cleanup { + sh script: 'vagrant destroy -f --no-parallel -g', + label: 'Destroy VMs' + cleanWs() + } + } +} + +def targetDistroSpec(distro) { + def spec = [:] + + switch (distro) { + case 'almalinux-9': + vm = 'almalinux_9' + ldata = 'leapp-data-almalinux' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + case 'rocky-9': + vm = 'rocky_9' + ldata = 'leapp-data-rocky' + + spec = [ + vmName: vm, + leappData: ldata + ] + break + default: + spec = [ + vmName: 'unknown', + leappData: 'unknown' + ] + break + } + return spec +} diff --git a/ci/jenkins/ELevate_el8toel9_Testing.jenkinsfile b/ci/jenkins/ELevate_el8toel9_Testing.jenkinsfile new file mode 100644 index 00000000..79cdd472 --- /dev/null +++ b/ci/jenkins/ELevate_el8toel9_Testing.jenkinsfile @@ -0,0 +1,187 @@ +RETRY = params.RETRY +TIMEOUT = params.TIMEOUT + +pipeline { + agent { + label params.AGENT + } + options { + timestamps() + } + parameters { + string(name: 'AGENT', defaultValue: 'almalinux-8-vagrant-libvirt-x86_64', description: 'Input label of the Jenkins Agent', trim: true) + string(name: 'RETRY', defaultValue: '3', description: 'Input count of retry', trim: true) + string(name: 'TIMEOUT', defaultValue: '60', description: 'Input timeout value in minutes', trim: true) + string(name: 'REPO_URL', defaultValue: 'https://github.com/LKHN/el-test-auto-dev.git', description: 'URL of the pipeline repository', trim: true) + string(name: 'REPO_BRANCH', defaultValue: 'main', description: 'Branch of the pipeline repository', trim: true) + choice(name: 'SOURCE_DISTRO_FILTER', choices: ['almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8', 'all'], description: 'Select a source distro or all for ELevation') + choice(name: 'TARGET_DISTRO_FILTER', choices: ['almalinux-9', 'centos-stream-9', 'oraclelinux-9', 'rocky-9', 'all'], description: 'Select a target distro or all to ELevation') + choice(name: 'CONF_FILTER', choices: ['minimal', 'docker-ce'], description: 'Select a configuration') + } + stages { + stage('Source') { + steps { + git url: REPO_URL, + branch: REPO_BRANCH, + credentialsId: 'github-almalinuxautobot' + } + } + stage('Prepare Build and Test enviroment') { + steps { + sh script: 'cp Vagrantfile.el8toel9 Vagrantfile', + label: 'Generate the el8toel9 Vagrantfile' + sh script: 'sudo dnf -y install python39-devel python39-wheel', + label: 'Install Python 3.9, PIP and Wheel' + sh script: 'sudo python3 -m pip install --no-cache-dir --upgrade -r requirements.txt', + label: 'Install TestInfra' + } + } + stage('ELevation') { + matrix { + when { + allOf { + anyOf { + expression { params.SOURCE_DISTRO_FILTER == 'all' } + expression { params.SOURCE_DISTRO_FILTER == env.SOURCE_DISTRO } + } + anyOf { + expression { params.TARGET_DISTRO_FILTER == 'all' } + expression { params.TARGET_DISTRO_FILTER == env.TARGET_DISTRO } + } + } + } + axes { + axis { + name 'SOURCE_DISTRO' + values 'almalinux-8', 'centos-stream-8', 'oraclelinux-8', 'rocky-8' + } + axis { + name 'TARGET_DISTRO' + values 'almalinux-9', 'centos-stream-9', 'oraclelinux-9', 'rocky-9' + } + } + stages { + stage('Create and Configure Machines') { + environment { + CONFIG = "${CONF_FILTER}" + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'vagrant destroy -f $SOURCE_DISTRO', + label: 'Make sure no machine present from the last retry' + sh script: 'vagrant up $SOURCE_DISTRO', + label: 'Create the source machines' + } + } + } + } + stage('ELevate to the all target distros') { + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo dnf config-manager --add-repo https://repo.almalinux.org/elevate/testing/elevate-testing.repo\"', + label: 'Add the ELevate Testing RPM repository' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo dnf -y install leapp-upgrade\"', + label: 'Install the leap rpm package' + script { + def LEAPP_DATA = getLeappDataDistro(TARGET_DISTRO) + sh(script:"vagrant ssh $SOURCE_DISTRO -c \"sudo dnf -y install leapp-data-$LEAPP_DATA\"", + label:'Install the LEAP migration data rpm packages') + sh(script:'vagrant ssh $SOURCE_DISTRO -c \"sudo dnf -y install tree && sudo tree -ha /etc/leapp\"', + label:'Debug: Data paths') + } + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo leapp preupgrade\"', + label: 'Start the Pre-Upgrade check', + returnStatus: true + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"echo PermitRootLogin yes | sudo tee -a /etc/ssh/sshd_config\"', + label: 'Permit ssh as root login' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo leapp answer --section remove_pam_pkcs11_module_check.confirm=True\"', + label: 'Answer the LEAP question' + sh script: 'vagrant ssh $SOURCE_DISTRO -c \"sudo leapp upgrade\"', + label: 'Start the Upgrade' + sh script: 'vagrant reload $SOURCE_DISTRO', + label: 'Reboot to the ELevate initramfs' + sh script: 'vagrant ssh-config $SOURCE_DISTRO >> .vagrant/ssh-config', + label: 'Generate the ssh-config file' + } + } + } + } + stage('Distro Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'minimal'} + expression { params.CONF_FILTER == 'docker-ce'} + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'py.test -v --hosts=$SOURCE_DISTRO --ssh-config=.vagrant/ssh-config --junit-xml tests/distro/test_osinfo_$TARGET_DISTRO-junit.xml tests/distro/test_osinfo_$TARGET_DISTRO.py', + label: 'Run the distro specific tests' + } + } + } + } + stage('Docker Tests') { + when { + anyOf { + expression { params.CONF_FILTER == 'docker-ce'} + } + } + steps { + retry(RETRY) { + timeout(time: TIMEOUT, unit: 'MINUTES') { + sh script: 'py.test -v --hosts=$SOURCE_DISTRO --ssh-config=.vagrant/ssh-config --junit-xml tests/docker/test_docker_ce_$SOURCE_DISTRO-junit.xml tests/docker/test_docker_ce.py', + label: 'Run the distro specific tests' + } + } + } + } + } + } + } + } + post { + success { + junit testResults: '**/tests/**/**-junit.xml', + skipPublishingChecks: true + } + cleanup { + sh script: 'vagrant destroy -f', + label: 'Destroy All Machines' + cleanWs() + } + } +} + +/* +* Common Functions +*/ +def getLeappDataDistro(TARGET_DISTRO) { + def leapp_data = "" + + switch(TARGET_DISTRO) { + case "almalinux-9": + leapp_data = TARGET_DISTRO.substring(0, 9) + break + + case "centos-stream-9": + leapp_data = TARGET_DISTRO.substring(0, 6) + break + + case "oraclelinux-9": + leapp_data = TARGET_DISTRO.substring(0, 11) + break + + case "rocky-9": + leapp_data = TARGET_DISTRO.substring(0, 5) + break + + default: + leap_data = "Error: Target Distro Not Supported" + break + } + return leapp_data +} diff --git a/ci/scripts/install_elevate_dev.sh b/ci/scripts/install_elevate_dev.sh new file mode 100644 index 00000000..f9cc2903 --- /dev/null +++ b/ci/scripts/install_elevate_dev.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +USER='AlmaLinux' +BRANCH='almalinux' + +show_usage() { + echo 'Usage: sync_cloudlinux [OPTION]...' + echo '' + echo ' -h, --help show this message and exit' + echo ' -u, --user github user name (default: AlmaLinux)' + echo ' -b, --branch github branch name (default: almalinux)' +} + +while [[ $# -gt 0 ]]; do + opt="$1" + case ${opt} in + -h|--help) + show_usage + exit 0 + ;; + -u|--user) + USER="$2" + shift + shift + ;; + -b|--branch) + BRANCH="$2" + shift + shift + ;; + *) + echo -e "Error: unknown option ${opt}" >&2 + exit 2 + ;; + esac +done + +RHEL_MAJOR_VERSION=$(rpm --eval %rhel) +WORK_DIR="$HOME" +NEW_LEAPP_NAME="leapp-repository-$BRANCH" +NEW_LEAPP_DIR="$WORK_DIR/$NEW_LEAPP_NAME/" +LEAPP_PATH='/usr/share/leapp-repository/repositories/' +LEAPP_GPG_PATH='/etc/leapp/repos.d/system_upgrade/common/files/rpm-gpg' +EXCLUDE_PATH=' +/usr/share/leapp-repository/repositories/system_upgrade/el7toel8/files/bundled-rpms +/usr/share/leapp-repository/repositories/system_upgrade/el7toel8/files +/usr/share/leapp-repository/repositories/system_upgrade/el7toel8 +/usr/share/leapp-repository/repositories/system_upgrade/el8toel9/files/bundled-rpms +/usr/share/leapp-repository/repositories/system_upgrade/el8toel9/files +/usr/share/leapp-repository/repositories/system_upgrade/el8toel9 +/usr/share/leapp-repository/repositories/system_upgrade +/usr/share/leapp-repository/repositories/ +' + + +echo "RHEL_MAJOR_VERSION=$RHEL_MAJOR_VERSION" +echo "WORK_DIR=$WORK_DIR" +echo "EXCLUDED_PATHS=$EXCLUDE_PATH" + +echo "Preserve GPG keys if any" +for major in 8 9; do + test -e ${LEAPP_GPG_PATH}/${major} && mv ${LEAPP_GPG_PATH}/${major} ${WORK_DIR}/ +done + + +echo 'Remove old files' +for dir in $(find $LEAPP_PATH -type d); +do + skip=0 + for exclude in $(echo $EXCLUDE_PATH); + do + if [[ $exclude == $dir ]];then + skip=1 + break + fi + done + if [ $skip -eq 0 ];then + rm -rf $dir + fi +done + +echo "Download new tarball from https://github.com/$USER/leapp-repository/archive/$BRANCH/leapp-repository-$BRANCH.tar.gz" +curl -s -L https://github.com/$USER/leapp-repository/archive/$BRANCH/leapp-repository-$BRANCH.tar.gz | tar -xmz -C $WORK_DIR/ || exit 1 + +echo 'Deleting files as in spec file' +rm -rf $NEW_LEAPP_DIR/repos/common/actors/testactor +find $NEW_LEAPP_DIR/repos/common -name "test.py" -delete +rm -rf `find $NEW_LEAPP_DIR -name "tests" -type d` +find $NEW_LEAPP_DIR -name "Makefile" -delete +if [ $RHEL_MAJOR_VERSION -eq '7' ]; then + rm -rf $NEW_LEAPP_DIR/repos/system_upgrade/el8toel9 +else + rm -rf $NEW_LEAPP_DIR/repos/system_upgrade/el7toel8 + rm -rf $NEW_LEAPP_DIR/repos/system_upgrade/cloudlinux +fi + +echo 'Copy new data to system' +cp -r $NEW_LEAPP_DIR/repos/* $LEAPP_PATH || exit 1 + +for DIRECTORY in $(find $LEAPP_PATH -mindepth 1 -maxdepth 1 -type d); +do + REPOSITORY=$(basename $DIRECTORY) + if ! [ -e /etc/leapp/repos.d/$REPOSITORY ];then + echo "Enabling repository $REPOSITORY" + ln -s $LEAPP_PATH/$REPOSITORY /etc/leapp/repos.d/$REPOSITORY || exit 1 + fi +done + +echo "Restore GPG keys if any" +for major in 8 9; do + rm -rf ${LEAPP_GPG_PATH}/${major} + test -e ${WORK_DIR}/${major} && mv ${WORK_DIR}/${major} ${LEAPP_GPG_PATH}/ +done + +rm -rf $NEW_LEAPP_DIR + +exit 0 diff --git a/ci/tests/tests/conftest.py b/ci/tests/tests/conftest.py new file mode 100644 index 00000000..01f9443e --- /dev/null +++ b/ci/tests/tests/conftest.py @@ -0,0 +1,52 @@ +import pytest +import re + + +@pytest.fixture(scope="module") +def get_os_release(host): + """Get content of the /etc/os-release""" + os_release = host.file("/etc/os-release") + return os_release + + +@pytest.fixture(scope="module") +def get_redhat_release(host): + """Get content of the /etc/redhat-release""" + redhat_release = host.file("/etc/redhat-release") + return redhat_release + + +@pytest.fixture(scope="module") +def get_kernel_info(host): + """Get kernel version and vendor information""" + kernel_ver_pattern = re.compile( + f".*(^[0-9][0-9]?[0-9]?.[0-9][0-9]?[0-9]?.[0-9][0-9]?[0-9]?).*" + ) + kernel_ver_output = host.check_output("uname -r") + kernel_version = kernel_ver_pattern.match(kernel_ver_output).group(1) + + with host.sudo(): + kernel_vendor = host.check_output( + "grep -Ei '(.*kernel signing key|.*CA Server|.*Build)' /proc/keys | sed -E" + " 's/ +/:/g' | cut -d ':' -f 9 | uniq" + ) + kernel_info = (kernel_version, kernel_vendor) + return kernel_info + + +@pytest.fixture(scope="module", params=["glibc", "systemd", "coreutils", "rpm"]) +def get_pkg_info(host, request): + """Get vendor and version of installed packages""" + pkg_name = request.param + pkg_vendor = host.check_output( + f"rpm -qa --queryformat \"%{{VENDOR}}\n\" {request.param} | sed '$p;d' " + ) + pkg_version = host.check_output( + f'rpm -qa --queryformat "%{{VERSION}}\n" {request.param} | sort -n | sed' + " '$p;d'" + ) + pkg_info = (pkg_name, pkg_vendor, pkg_version) + # print(pkg_name) + # print(pkg_vendor) + # print(pkg_version) + return pkg_info diff --git a/ci/tests/tests/distro/test_osinfo_almalinux_8.py b/ci/tests/tests/distro/test_osinfo_almalinux_8.py new file mode 100644 index 00000000..c5219b35 --- /dev/null +++ b/ci/tests/tests/distro/test_osinfo_almalinux_8.py @@ -0,0 +1,43 @@ +import pytest + + +@pytest.mark.usefixtures("get_os_release") +class TestOSRelease: + """Test values of NAME, ID and VERSION_ID""" + + def test_os_rel_name(self, get_os_release): + assert get_os_release.contains('NAME="AlmaLinux"') + + def test_os_rel_id(self, get_os_release): + assert get_os_release.contains('ID="almalinux"') + + def test_os_rel_version_id(self, get_os_release): + assert get_os_release.contains('VERSION_ID="8.*"') + + +@pytest.mark.usefixtures("get_redhat_release") +class TestRHRelease: + """Test contents of the /etc/redhat-release""" + + def test_redhat_release(self, get_redhat_release): + assert get_redhat_release.contains("AlmaLinux release 8.*") + + +@pytest.mark.usefixtures("get_pkg_info") +class TestPkgInfo: + """Test vendor and version of packages""" + + def test_pkg_vendor(self, get_pkg_info): + assert get_pkg_info[1] == "AlmaLinux" + + def test_pkg_version(self, get_pkg_info): + if get_pkg_info[0] == "kernel": + assert get_pkg_info[2] == "4.18.0" + elif get_pkg_info[0] == "glibc": + assert get_pkg_info[2] == "2.28" + elif get_pkg_info[0] == "systemd": + assert get_pkg_info[2] == "239" + elif get_pkg_info[0] == "coreutils": + assert get_pkg_info[2] == "8.30" + else: + assert get_pkg_info[2] == "4.14.3" diff --git a/ci/tests/tests/distro/test_osinfo_almalinux_9.py b/ci/tests/tests/distro/test_osinfo_almalinux_9.py new file mode 100644 index 00000000..1536e52b --- /dev/null +++ b/ci/tests/tests/distro/test_osinfo_almalinux_9.py @@ -0,0 +1,52 @@ +import pytest + + +@pytest.mark.usefixtures("get_os_release") +class TestOSRelease: + """Test values of NAME, ID and VERSION_ID""" + + def test_os_rel_name(self, get_os_release): + assert get_os_release.contains('NAME="AlmaLinux"') + + def test_os_rel_id(self, get_os_release): + assert get_os_release.contains('ID="almalinux"') + + def test_os_rel_version_id(self, get_os_release): + assert get_os_release.contains('VERSION_ID="9.*"') + + +@pytest.mark.usefixtures("get_redhat_release") +class TestRHRelease: + """Test contents of the /etc/redhat-release""" + + def test_redhat_release(self, get_redhat_release): + assert get_redhat_release.contains("AlmaLinux release 9.*") + + +@pytest.mark.usefixtures("get_kernel_info") +class TestKernelInfo: + """Test version and vendor of running kernel""" + + def test_kernel_version(self, get_kernel_info): + assert get_kernel_info[0] == "5.14.0" + + def test_kernel_vendor(self, get_kernel_info): + assert get_kernel_info[1] == "AlmaLinux" + + +@pytest.mark.usefixtures("get_pkg_info") +class TestPkgInfo: + """Test vendor and version of packages""" + + def test_pkg_vendor(self, get_pkg_info): + assert get_pkg_info[1] == "AlmaLinux" + + def test_pkg_version(self, get_pkg_info): + if get_pkg_info[0] == "glibc": + assert get_pkg_info[2] == "2.34" + elif get_pkg_info[0] == "systemd": + assert get_pkg_info[2] == "252" + elif get_pkg_info[0] == "coreutils": + assert get_pkg_info[2] == "8.32" + else: + assert get_pkg_info[2] == "4.16.1.3" diff --git a/ci/tests/tests/distro/test_osinfo_centosstream_8.py b/ci/tests/tests/distro/test_osinfo_centosstream_8.py new file mode 100644 index 00000000..995ae61e --- /dev/null +++ b/ci/tests/tests/distro/test_osinfo_centosstream_8.py @@ -0,0 +1,23 @@ +import pytest + + +@pytest.mark.usefixtures("get_os_release") +class TestOSRelease: + """Test values of NAME, ID and VERSION_ID""" + + def test_os_rel_name(self, get_os_release): + assert get_os_release.contains('NAME="CentOS Stream"') + + def test_os_rel_id(self, get_os_release): + assert get_os_release.contains('ID="centos"') + + def test_os_rel_version_id(self, get_os_release): + assert get_os_release.contains('VERSION_ID="8"') + + +@pytest.mark.usefixtures("get_redhat_release") +class TestRHRelease: + """Test contents of the /etc/redhat-release""" + + def test_redhat_release(self, get_redhat_release): + assert get_redhat_release.contains("CentOS Stream release 8") diff --git a/ci/tests/tests/distro/test_osinfo_centosstream_9.py b/ci/tests/tests/distro/test_osinfo_centosstream_9.py new file mode 100644 index 00000000..28e47202 --- /dev/null +++ b/ci/tests/tests/distro/test_osinfo_centosstream_9.py @@ -0,0 +1,23 @@ +import pytest + + +@pytest.mark.usefixtures("get_os_release") +class TestOSRelease: + """Test values of NAME, ID and VERSION_ID""" + + def test_os_rel_name(self, get_os_release): + assert get_os_release.contains('NAME="CentOS Stream"') + + def test_os_rel_id(self, get_os_release): + assert get_os_release.contains('ID="centos"') + + def test_os_rel_version_id(self, get_os_release): + assert get_os_release.contains('VERSION_ID="9"') + + +@pytest.mark.usefixtures("get_redhat_release") +class TestRHRelease: + """Test contents of the /etc/redhat-release""" + + def test_redhat_release(self, get_redhat_release): + assert get_redhat_release.contains("CentOS Stream release 9") diff --git a/ci/tests/tests/distro/test_osinfo_oraclelinux_8.py b/ci/tests/tests/distro/test_osinfo_oraclelinux_8.py new file mode 100644 index 00000000..2080fd2f --- /dev/null +++ b/ci/tests/tests/distro/test_osinfo_oraclelinux_8.py @@ -0,0 +1,23 @@ +import pytest + + +@pytest.mark.usefixtures("get_os_release") +class TestOSRelease: + """Test values of NAME, ID and VERSION_ID""" + + def test_os_rel_name(self, get_os_release): + assert get_os_release.contains('NAME="Oracle Linux Server"') + + def test_os_rel_id(self, get_os_release): + assert get_os_release.contains('ID="ol"') + + def test_os_rel_version_id(self, get_os_release): + assert get_os_release.contains('VERSION_ID="8.*"') + + +@pytest.mark.usefixtures("get_redhat_release") +class TestRHRelease: + """Test contents of the /etc/redhat-release""" + + def test_redhat_release(self, get_redhat_release): + assert get_redhat_release.contains("Red Hat Enterprise Linux release 8.*") diff --git a/ci/tests/tests/distro/test_osinfo_oraclelinux_9.py b/ci/tests/tests/distro/test_osinfo_oraclelinux_9.py new file mode 100644 index 00000000..bd5044bb --- /dev/null +++ b/ci/tests/tests/distro/test_osinfo_oraclelinux_9.py @@ -0,0 +1,23 @@ +import pytest + + +@pytest.mark.usefixtures("get_os_release") +class TestOSRelease: + """Test values of NAME, ID and VERSION_ID""" + + def test_os_rel_name(self, get_os_release): + assert get_os_release.contains('NAME="Oracle Linux Server"') + + def test_os_rel_id(self, get_os_release): + assert get_os_release.contains('ID="ol"') + + def test_os_rel_version_id(self, get_os_release): + assert get_os_release.contains('VERSION_ID="9.*"') + + +@pytest.mark.usefixtures("get_redhat_release") +class TestRHRelease: + """Test contents of the /etc/redhat-release""" + + def test_redhat_release(self, get_redhat_release): + assert get_redhat_release.contains("Red Hat Enterprise Linux release 9.*") diff --git a/ci/tests/tests/distro/test_osinfo_rocky_8.py b/ci/tests/tests/distro/test_osinfo_rocky_8.py new file mode 100644 index 00000000..cce5d668 --- /dev/null +++ b/ci/tests/tests/distro/test_osinfo_rocky_8.py @@ -0,0 +1,23 @@ +import pytest + + +@pytest.mark.usefixtures("get_os_release") +class TestOSRelease: + """Test values of NAME, ID and VERSION_ID""" + + def test_os_rel_name(self, get_os_release): + assert get_os_release.contains('NAME="Rocky Linux"') + + def test_os_rel_id(self, get_os_release): + assert get_os_release.contains('ID="rocky"') + + def test_os_rel_version_id(self, get_os_release): + assert get_os_release.contains('VERSION_ID="8.*"') + + +@pytest.mark.usefixtures("get_redhat_release") +class TestRHRelease: + """Test contents of the /etc/redhat-release""" + + def test_redhat_release(self, get_redhat_release): + assert get_redhat_release.contains("Rocky Linux release 8.*") diff --git a/ci/tests/tests/distro/test_osinfo_rocky_9.py b/ci/tests/tests/distro/test_osinfo_rocky_9.py new file mode 100644 index 00000000..ce8cccdb --- /dev/null +++ b/ci/tests/tests/distro/test_osinfo_rocky_9.py @@ -0,0 +1,23 @@ +import pytest + + +@pytest.mark.usefixtures("get_os_release") +class TestOSRelease: + """Test values of NAME, ID and VERSION_ID""" + + def test_os_rel_name(self, get_os_release): + assert get_os_release.contains('NAME="Rocky Linux"') + + def test_os_rel_id(self, get_os_release): + assert get_os_release.contains('ID="rocky"') + + def test_os_rel_version_id(self, get_os_release): + assert get_os_release.contains('VERSION_ID="9.*"') + + +@pytest.mark.usefixtures("get_redhat_release") +class TestRHRelease: + """Test contents of the /etc/redhat-release""" + + def test_redhat_release(self, get_redhat_release): + assert get_redhat_release.contains("Rocky Linux release 9.*") diff --git a/ci/tests/tests/docker/test_docker_ce.py b/ci/tests/tests/docker/test_docker_ce.py new file mode 100644 index 00000000..3c2550c7 --- /dev/null +++ b/ci/tests/tests/docker/test_docker_ce.py @@ -0,0 +1,26 @@ +import pytest + + +class TestDockerServices: + """Test docker and containerd services running and enabled""" + + def test_docker_is_running(self, host): + assert host.service("docker.service").is_running + + def test_containerd_is_running(self, host): + assert host.service("containerd.service").is_running + + def test_docker_is_enabled(self, host): + assert host.service("docker.service").is_enabled + + def test_containerd_is_enabled(self, host): + assert host.service("containerd.service").is_enabled + + +class TestDockerWorking: + """Test docker working with the hello world container""" + + def test_docker_is_working(self, host): + with host.sudo(): + cmd = host.run("sudo docker run --rm hello-world") + assert cmd.succeeded diff --git a/ci/vagrant/el7toel8_multi.rb b/ci/vagrant/el7toel8_multi.rb new file mode 100644 index 00000000..a18da81d --- /dev/null +++ b/ci/vagrant/el7toel8_multi.rb @@ -0,0 +1,40 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +configuration = ENV['CONFIG'] + +Vagrant.configure('2') do |config| + config.vagrant.plugins = 'vagrant-libvirt' + + config.vm.synced_folder '.', '/vagrant', disabled: true + config.vm.box = 'generic/centos7' + config.vm.boot_timeout = 3600 + + config.vm.provider 'libvirt' do |v| + v.uri = 'qemu:///system' + v.memory = 4096 + v.machine_type = 'q35' + v.cpu_mode = 'host-passthrough' + v.cpus = 2 + v.disk_bus = 'scsi' + v.disk_driver cache: 'writeback', discard: 'unmap' + v.random_hostname = true + end + + target_distros = ['almalinux', 'centosstream', 'oraclelinux', 'rocky'] + + target_distros.each do |target_distro| + config.vm.define "#{target_distro}_8" do |machine| + machine.vm.hostname = "#{target_distro}-8.test" + + if target_distro == target_distros[-1] + machine.vm.provision 'ansible' do |ansible| + ansible.compatibility_mode = '2.0' + ansible.limit = 'all' + ansible.playbook = "ci/ansible/#{configuration}.yaml" + ansible.config_file = 'ci/ansible/ansible.cfg' + end + end + end + end +end diff --git a/ci/vagrant/el7toel8toel9_single.rb b/ci/vagrant/el7toel8toel9_single.rb new file mode 100644 index 00000000..8cd05ac3 --- /dev/null +++ b/ci/vagrant/el7toel8toel9_single.rb @@ -0,0 +1,53 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +configuration = ENV['CONFIG'] + +Vagrant.configure('2') do |config| + config.vagrant.plugins = 'vagrant-libvirt' + + config.vm.synced_folder '.', '/vagrant', disabled: true + config.ssh.disable_deprecated_algorithms = true + config.vm.boot_timeout = 3600 + + config.vm.provider 'libvirt' do |v| + v.uri = 'qemu:///system' + v.memory = 4096 + v.machine_type = 'q35' + v.cpu_mode = 'host-passthrough' + v.cpus = 2 + v.disk_bus = 'scsi' + v.disk_driver cache: 'writeback', discard: 'unmap' + v.random_hostname = true + end + + # EL7toEL8 + target_distros = ['almalinux', 'centosstream', 'oraclelinux', 'rocky'] + + target_distros.each do |target_distro| + config.vm.define "#{target_distro}_8" do |machine| + machine.vm.box = 'generic/centos7' + machine.vm.hostname = "#{target_distro}-8.test" + end + end + + # EL8toEL9 + target_distros_el9 = { + almalinux: 'almalinux/8', + # centosstream: 'generic/centos8s', + rocky: 'generic/rocky8' + } + + target_distros_el9.each_pair do |vm, box| + config.vm.define "#{vm}_9" do |machine| + machine.vm.box = "#{box}" + machine.vm.hostname = "#{vm}-9.test" + end + end + + config.vm.provision 'ansible' do |ansible| + ansible.compatibility_mode = '2.0' + ansible.playbook = "ci/ansible/#{configuration}.yaml" + ansible.config_file = 'ci/ansible/ansible.cfg' + end +end diff --git a/ci/vagrant/el8toel9_multi.rb b/ci/vagrant/el8toel9_multi.rb new file mode 100644 index 00000000..370758e6 --- /dev/null +++ b/ci/vagrant/el8toel9_multi.rb @@ -0,0 +1,45 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +configuration = ENV['CONFIG'] + +Vagrant.configure('2') do |config| + config.vagrant.plugins = 'vagrant-libvirt' + + config.vm.synced_folder '.', '/vagrant', disabled: true + config.ssh.disable_deprecated_algorithms = true + config.vm.boot_timeout = 3600 + + config.vm.provider 'libvirt' do |v| + v.uri = 'qemu:///system' + v.memory = 4096 + v.machine_type = 'q35' + v.cpu_mode = 'host-passthrough' + v.cpus = 2 + v.disk_bus = 'scsi' + v.disk_driver cache: 'writeback', discard: 'unmap' + v.random_hostname = true + end + + target_distros = { + almalinux: 'almalinux/8', + # centosstream: 'generic/centos8s', + rocky: 'generic/rocky8' + } + + target_distros.each_pair do |vm, box| + config.vm.define "#{vm}_9" do |machine| + machine.vm.box = "#{box}" + machine.vm.hostname = "#{vm}-9.test" + + if [vm, box] == target_distros.to_a.last + machine.vm.provision 'ansible' do |ansible| + ansible.compatibility_mode = '2.0' + ansible.limit = 'all' + ansible.playbook = "ci/ansible/#{configuration}.yaml" + ansible.config_file = 'ci/ansible/ansible.cfg' + end + end + end + end +end diff --git a/commands/command_utils.py b/commands/command_utils.py index e6ba6ba4..647e7b44 100644 --- a/commands/command_utils.py +++ b/commands/command_utils.py @@ -36,11 +36,13 @@ class _VersionKind(str, Enum): class DistroIDs(str, Enum): RHEL = 'rhel' CENTOS = 'centos' + ALMALINUX = 'almalinux' _DISTRO_VERSION_FORMATS = { DistroIDs.RHEL: VersionFormats.MAJOR_MINOR, DistroIDs.CENTOS: VersionFormats.MAJOR_ONLY, + DistroIDs.ALMALINUX: VersionFormats.MAJOR_MINOR, } """ Maps distro ID to the expected OS version format. @@ -134,6 +136,16 @@ def get_os_release_version_id(filepath): return _retrieve_os_release_contents(_os_release_path=filepath).get('VERSION_ID', '') +def get_distro_id(): + """ + Retrieve the OS release ID from /etc/os-release. + + :return: The OS release ID from /etc/os-release + :rtype: str + """ + return _retrieve_os_release_contents('/etc/os-release').get('ID', '') + + def get_upgrade_paths_config(): # NOTE(ivasilev) Importing here not to have circular dependencies from leapp.cli.commands.upgrade import util # noqa: C415; pylint: disable=import-outside-toplevel @@ -203,8 +215,7 @@ def get_target_release(args): target_ver = env_version_override or args.target if target_ver: - os_release_contents = _retrieve_os_release_contents() - distro_id = os_release_contents.get('ID', '') + distro_id = get_distro_id() expected_version_format = _DISTRO_VERSION_FORMATS.get(distro_id, VersionFormats.MAJOR_MINOR).value assert_version_format(target_ver, expected_version_format, _VersionKind.TARGET) return (target_ver, flavor) diff --git a/commands/preupgrade/__init__.py b/commands/preupgrade/__init__.py index e52b6561..6443bd8a 100644 --- a/commands/preupgrade/__init__.py +++ b/commands/preupgrade/__init__.py @@ -20,8 +20,12 @@ from leapp.utils.output import beautify_actor_exception, report_errors, report_i choices=list(util.EXPERIMENTAL_FEATURES), default=[]) @command_opt('debug', is_flag=True, help='Enable debug mode', inherit=False) @command_opt('verbose', is_flag=True, help='Enable verbose logging', inherit=False) -@command_opt('no-rhsm', is_flag=True, help='Use only custom repositories and skip actions' - ' with Red Hat Subscription Manager') +@command_opt( + 'no-rhsm', + is_flag=True, + help='Use only custom repositories and skip actions with Red Hat Subscription Manager.' + ' This only has effect on Red Hat Enterprise Linux systems.' +) @command_opt('no-insights-register', is_flag=True, help='Do not register into Red Hat Insights') @command_opt('no-rhsm-facts', is_flag=True, help='Do not store migration information using Red Hat ' 'Subscription Manager. Automatically implied by --no-rhsm.') diff --git a/commands/upgrade/__init__.py b/commands/upgrade/__init__.py index 6f7504bf..36be0719 100644 --- a/commands/upgrade/__init__.py +++ b/commands/upgrade/__init__.py @@ -26,8 +26,12 @@ from leapp.utils.output import beautify_actor_exception, report_errors, report_i choices=list(util.EXPERIMENTAL_FEATURES), default=[]) @command_opt('debug', is_flag=True, help='Enable debug mode', inherit=False) @command_opt('verbose', is_flag=True, help='Enable verbose logging', inherit=False) -@command_opt('no-rhsm', is_flag=True, help='Use only custom repositories and skip actions' - ' with Red Hat Subscription Manager') +@command_opt( + 'no-rhsm', + is_flag=True, + help='Use only custom repositories and skip actions with Red Hat Subscription Manager.' + ' This only has effect on Red Hat Enterprise Linux systems.' +) @command_opt('no-insights-register', is_flag=True, help='Do not register into Red Hat Insights') @command_opt('no-rhsm-facts', is_flag=True, help='Do not store migration information using Red Hat ' 'Subscription Manager. Automatically implied by --no-rhsm.') diff --git a/commands/upgrade/util.py b/commands/upgrade/util.py index 7d5b563e..dadfe7de 100644 --- a/commands/upgrade/util.py +++ b/commands/upgrade/util.py @@ -222,7 +222,8 @@ def prepare_configuration(args): os.environ['LEAPP_EXPERIMENTAL'] = '1' os.environ['LEAPP_UNSUPPORTED'] = '0' if os.getenv('LEAPP_UNSUPPORTED', '0') == '0' else '1' - if args.no_rhsm: + # force no rhsm on non-rhel systems, regardless of whether the binary is there + if args.no_rhsm or command_utils.get_distro_id() != 'rhel': os.environ['LEAPP_NO_RHSM'] = '1' elif not os.path.exists('/usr/sbin/subscription-manager'): os.environ['LEAPP_NO_RHSM'] = '1' diff --git a/docs/source/libraries-and-api/deprecations-list.md b/docs/source/libraries-and-api/deprecations-list.md index b3abfc5d..8b419800 100644 --- a/docs/source/libraries-and-api/deprecations-list.md +++ b/docs/source/libraries-and-api/deprecations-list.md @@ -1,7 +1,7 @@ # Deprecated functionality Deprecated functionality is listed under the first version that the functionality -is deprecated in. Note that functionality may be deprecated in later versions -but are not listed again. +is deprecated in. Note that functionality may be removed in later versions +but will not be listed again. The dates in brackets correspond to the end of the deprecation protection period, after which the related functionality can be removed at any time. @@ -17,7 +17,8 @@ Only the versions in which a deprecation has been made are listed. - Shared libraries - **`leapp.libraries.common.config.version.SUPPORTED_VERSIONS`** - The `SUPPORTED_VERSIONS` dict has been deprecated as it is problematic with the new design. Use `leapp.libraries.common.config.version.is_supported_version()` or `IPUConfig.supported_upgrade_paths` instead. - **`leapp.libraries.common.config.version.is_rhel_alt()`** - The function can return only `False` nowadays as RHEL-ALT 7 is EOL for years and future version of leapp-repository will not support RHEL 7 anymore. - +- Models + - **`InstalledUnsignedRPM`** - Replaced by the distribution agnostic `ThirdPartyRPM`. ## v0.20.0 (till September 2024) - Models diff --git a/etc/fapolicyd/rules.d/31-leapp-repository.rules b/etc/fapolicyd/rules.d/31-leapp-repository.rules new file mode 100644 index 00000000..2fd3dc6e --- /dev/null +++ b/etc/fapolicyd/rules.d/31-leapp-repository.rules @@ -0,0 +1,2 @@ +allow perm=any all : dir=/var/lib/leapp/ + diff --git a/etc/leapp/files/device_driver_deprecation_data.json b/etc/leapp/files/device_driver_deprecation_data.json index 4531fb08..6d5d6ef9 100644 --- a/etc/leapp/files/device_driver_deprecation_data.json +++ b/etc/leapp/files/device_driver_deprecation_data.json @@ -2726,7 +2726,7 @@ ], "deprecation_announced": "", "device_id": "0x9005:0x0200:0x9005:0x0200", - "device_name": "", + "device_name": "Adaptec: AAC-RAID: Themisto Jupiter Platform", "device_type": "pci", "driver_name": "aacraid", "maintained_in_rhel": [ @@ -2824,6 +2824,19 @@ 7 ] }, + { + "available_in_rhel": [ + 7 + ], + "deprecation_announced": "", + "device_id": "0x9005:0x0285:0x1028:0x0291", + "device_name": "Adaptec: AAC-RAID: CERC SATA RAID 2 PCI SATA 6ch (DellCorsair)", + "device_type": "pci", + "driver_name": "aacraid", + "maintained_in_rhel": [ + 7 + ] + }, { "available_in_rhel": [ 7 @@ -3363,7 +3376,7 @@ ], "deprecation_announced": "", "device_id": "0x9005:0x0287:0x9005:0x0800", - "device_name": "", + "device_name": "Adaptec: AAC-RAID: Themisto Jupiter Platform", "device_type": "pci", "driver_name": "aacraid", "maintained_in_rhel": [ @@ -3376,7 +3389,7 @@ ], "deprecation_announced": "", "device_id": "0x9005:0x0288", - "device_name": "", + "device_name": "Adaptec: AAC-RAID: NEMER/ARK Catch All", "device_type": "pci", "driver_name": "aacraid", "maintained_in_rhel": [ diff --git a/etc/leapp/files/pes-events.json b/etc/leapp/files/pes-events.json index e9da4873..da62837f 100644 --- a/etc/leapp/files/pes-events.json +++ b/etc/leapp/files/pes-events.json @@ -1,5 +1,5 @@ { -"timestamp": "202505191506Z", +"timestamp": "202507291505Z", "provided_data_streams": [ "4.0" ], @@ -71305,9 +71305,6 @@ null { "action": 1, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 2129, @@ -71318,14 +71315,14 @@ null null ], "name": "libasan-static", -"repository": "rhel7-base" +"repository": "rhel7-optional" } ], "set_id": 3509 }, "initial_release": { "major_version": 7, -"minor_version": 7, +"minor_version": 9, "os_name": "RHEL" }, "modulestream_maps": [], @@ -71339,7 +71336,6 @@ null { "action": 1, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -71359,7 +71355,7 @@ null }, "initial_release": { "major_version": 7, -"minor_version": 7, +"minor_version": 9, "os_name": "RHEL" }, "modulestream_maps": [], @@ -71373,7 +71369,6 @@ null { "action": 1, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -71393,7 +71388,7 @@ null }, "initial_release": { "major_version": 7, -"minor_version": 7, +"minor_version": 9, "os_name": "RHEL" }, "modulestream_maps": [], @@ -71440,7 +71435,6 @@ null { "action": 1, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -71453,14 +71447,14 @@ null null ], "name": "libitm-static", -"repository": "rhel7-base" +"repository": "rhel7-optional" } ], "set_id": 3513 }, "initial_release": { "major_version": 7, -"minor_version": 7, +"minor_version": 9, "os_name": "RHEL" }, "modulestream_maps": [], @@ -71474,7 +71468,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -71487,14 +71480,14 @@ null null ], "name": "libmpc-devel", -"repository": "rhel7-base" +"repository": "rhel7-optional" } ], "set_id": 3514 }, "initial_release": { "major_version": 7, -"minor_version": 7, +"minor_version": 9, "os_name": "RHEL" }, "modulestream_maps": [ @@ -71510,7 +71503,7 @@ null null ], "name": "libmpc-devel", -"repository": "rhel8-AppStream" +"repository": "rhel8-CRB" } ], "set_id": 13111 @@ -139243,9 +139236,7 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", -"s390x", "x86_64" ], "id": 3917, @@ -139269,14 +139260,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "apache-commons-cli", "repository": "rhel8-AppStream" @@ -139348,7 +139345,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -139374,14 +139370,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "apache-commons-codec", "repository": "rhel8-AppStream" @@ -140187,7 +140189,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -140213,14 +140214,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "apache-commons-io", "repository": "rhel8-AppStream" @@ -140578,7 +140585,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -140604,14 +140610,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "apache-commons-lang3", "repository": "rhel8-AppStream" @@ -140683,7 +140695,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -140709,14 +140720,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "apache-commons-logging", "repository": "rhel8-AppStream" @@ -143567,7 +143584,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -143580,7 +143596,7 @@ null null ], "name": "cdi-api", -"repository": "rhel7-base" +"repository": "rhel7-optional" } ], "set_id": 6494 @@ -143593,14 +143609,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "cdi-api", "repository": "rhel8-AppStream" @@ -146083,7 +146105,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -146109,14 +146130,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "glassfish-el-api", "repository": "rhel8-AppStream" @@ -146578,7 +146605,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -146604,14 +146630,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "google-guice", "repository": "rhel8-AppStream" @@ -146859,7 +146891,10 @@ null "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "guice-grapher", "repository": "rhel8-CRB" @@ -146867,7 +146902,11 @@ null ], "set_id": 6604 }, -"initial_release": null, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, "modulestream_maps": [], "out_packageset": null, "release": { @@ -146889,7 +146928,10 @@ null "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "guice-jmx", "repository": "rhel8-CRB" @@ -146897,7 +146939,11 @@ null ], "set_id": 6605 }, -"initial_release": null, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, "modulestream_maps": [], "out_packageset": null, "release": { @@ -146919,7 +146965,10 @@ null "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "guice-jndi", "repository": "rhel8-CRB" @@ -146927,7 +146976,11 @@ null ], "set_id": 6606 }, -"initial_release": null, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, "modulestream_maps": [], "out_packageset": null, "release": { @@ -147153,7 +147206,6 @@ null { "action": 3, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -147179,14 +147231,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "guava20", "repository": "rhel8-AppStream" @@ -147672,7 +147730,14 @@ null "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +}, +{ +"name": "scala", +"stream": "2.10" +} ], "name": "hawtjni-runtime", "repository": "rhel8-AppStream" @@ -147680,7 +147745,11 @@ null ], "set_id": 6631 }, -"initial_release": null, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, "modulestream_maps": [], "out_packageset": null, "release": { @@ -147823,7 +147892,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -147849,14 +147917,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "httpcomponents-client", "repository": "rhel8-AppStream" @@ -147965,7 +148039,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -147991,14 +148064,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "httpcomponents-core", "repository": "rhel8-AppStream" @@ -152402,7 +152481,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -152428,14 +152506,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "scala", +"stream": "2.10" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "scala", +"stream": "2.10" +} ], "name": "jline", "repository": "rhel8-AppStream" @@ -152964,7 +153048,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -152990,14 +153073,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "jsoup", "repository": "rhel8-AppStream" @@ -153838,7 +153927,6 @@ null { "action": 3, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -153864,14 +153952,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "parfait", +"stream": "0.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "parfait", +"stream": "0.5" +} ], "name": "log4j12", "repository": "rhel8-AppStream" @@ -153888,7 +153982,6 @@ null { "action": 3, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -153914,14 +154007,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "parfait", +"stream": "0.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "parfait", +"stream": "0.5" +} ], "name": "log4j12-javadoc", "repository": "rhel8-AppStream" @@ -158469,7 +158568,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158495,14 +158593,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-annotations", "repository": "rhel8-CRB" @@ -158519,7 +158623,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158545,14 +158648,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-plugin", "repository": "rhel8-CRB" @@ -158569,7 +158678,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158595,14 +158703,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-tools", "repository": "rhel8-CRB" @@ -158619,7 +158733,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158645,14 +158758,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-tools-annotations", "repository": "rhel8-CRB" @@ -158669,7 +158788,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158695,14 +158813,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-tools-ant", "repository": "rhel8-CRB" @@ -158719,7 +158843,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158745,14 +158868,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-tools-api", "repository": "rhel8-CRB" @@ -158769,7 +158898,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158795,14 +158923,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-tools-beanshell", "repository": "rhel8-CRB" @@ -158819,7 +158953,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158845,14 +158978,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-tools-generators", "repository": "rhel8-CRB" @@ -158869,7 +159008,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158895,14 +159033,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-tools-java", "repository": "rhel8-CRB" @@ -158919,7 +159063,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158945,14 +159088,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-tools-javadoc", "repository": "rhel8-CRB" @@ -158969,7 +159118,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -158995,14 +159143,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-tools-javadocs", "repository": "rhel8-CRB" @@ -159019,7 +159173,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159045,14 +159198,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugin-tools-model", "repository": "rhel8-CRB" @@ -159069,7 +159228,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159095,14 +159253,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-script", "repository": "rhel8-CRB" @@ -159119,7 +159283,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159145,14 +159308,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-script-ant", "repository": "rhel8-CRB" @@ -159169,7 +159338,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159195,14 +159363,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-script-beanshell", "repository": "rhel8-CRB" @@ -159219,7 +159393,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159245,14 +159418,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-plugins-pom", "repository": "rhel8-CRB" @@ -159467,7 +159646,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159493,14 +159671,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-remote-resources-plugin", "repository": "rhel8-CRB" @@ -159517,7 +159701,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159543,14 +159726,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-remote-resources-plugin-javadoc", "repository": "rhel8-CRB" @@ -159567,7 +159756,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159593,14 +159781,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-reporting-api", "repository": "rhel8-CRB" @@ -159705,7 +159899,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159731,14 +159924,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-reporting-impl", "repository": "rhel8-CRB" @@ -159755,7 +159954,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159781,14 +159979,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-reporting-impl-javadoc", "repository": "rhel8-CRB" @@ -159871,7 +160075,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159897,14 +160100,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-resources-plugin", "repository": "rhel8-CRB" @@ -159921,7 +160130,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -159947,14 +160155,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-resources-plugin-javadoc", "repository": "rhel8-CRB" @@ -160070,7 +160284,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -160096,14 +160309,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-script-interpreter", "repository": "rhel8-CRB" @@ -160120,7 +160339,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -160146,14 +160364,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-script-interpreter-javadoc", "repository": "rhel8-CRB" @@ -160225,7 +160449,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -160251,14 +160474,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "maven-shade-plugin-javadoc", "repository": "rhel8-CRB" @@ -160616,7 +160845,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -160642,14 +160870,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "maven-shared-utils", "repository": "rhel8-AppStream" @@ -163885,7 +164119,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -163911,14 +164144,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-archiver", "repository": "rhel8-CRB" @@ -164210,7 +164449,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -164236,14 +164474,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "plexus-cipher", "repository": "rhel8-AppStream" @@ -164315,7 +164559,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -164341,14 +164584,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "plexus-classworlds", "repository": "rhel8-AppStream" @@ -164530,7 +164779,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -164556,14 +164804,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-compiler", "repository": "rhel8-CRB" @@ -164745,7 +164999,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -164771,14 +165024,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-component-api", "repository": "rhel8-CRB" @@ -164960,7 +165219,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -164986,14 +165244,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-containers", "repository": "rhel8-CRB" @@ -165010,7 +165274,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165036,14 +165299,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "plexus-containers-component-annotations", "repository": "rhel8-AppStream" @@ -165115,7 +165384,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165141,14 +165409,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-containers-component-metadata", "repository": "rhel8-CRB" @@ -165165,7 +165439,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165191,14 +165464,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-containers-container-default", "repository": "rhel8-CRB" @@ -165215,7 +165494,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165241,14 +165519,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-containers-javadoc", "repository": "rhel8-CRB" @@ -165265,7 +165549,6 @@ null { "action": 3, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165291,14 +165574,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-containers-component-metadata", "repository": "rhel8-CRB" @@ -165315,7 +165604,6 @@ null { "action": 3, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165341,14 +165629,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-containers-javadoc", "repository": "rhel8-CRB" @@ -165431,7 +165725,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165457,14 +165750,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-i18n", "repository": "rhel8-CRB" @@ -165481,7 +165780,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165507,14 +165805,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-i18n-javadoc", "repository": "rhel8-CRB" @@ -165531,7 +165835,6 @@ null { "action": 4, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165557,28 +165860,40 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-interactivity", "repository": "rhel8-CRB" }, { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-interactivity-api", "repository": "rhel8-CRB" }, { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-interactivity-jline", "repository": "rhel8-CRB" @@ -165595,7 +165910,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165621,14 +165935,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-interactivity-javadoc", "repository": "rhel8-CRB" @@ -165645,7 +165965,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165671,14 +165990,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "plexus-interpolation", "repository": "rhel8-AppStream" @@ -165695,7 +166020,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165721,14 +166045,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-interpolation-javadoc", "repository": "rhel8-CRB" @@ -165745,7 +166075,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -165771,14 +166100,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-io", "repository": "rhel8-CRB" @@ -165860,7 +166195,10 @@ null "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-languages", "repository": "rhel8-CRB" @@ -165868,7 +166206,11 @@ null ], "set_id": 7277 }, -"initial_release": null, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, "modulestream_maps": [], "out_packageset": null, "release": { @@ -165890,7 +166232,10 @@ null "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-languages-javadoc", "repository": "rhel8-CRB" @@ -165898,7 +166243,11 @@ null ], "set_id": 7278 }, -"initial_release": null, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, "modulestream_maps": [], "out_packageset": null, "release": { @@ -165976,7 +166325,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -166002,14 +166350,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-pom", "repository": "rhel8-CRB" @@ -166026,7 +166380,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -166052,14 +166405,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-resources", "repository": "rhel8-CRB" @@ -166076,7 +166435,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -166102,14 +166460,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "plexus-resources-javadoc", "repository": "rhel8-CRB" @@ -166126,7 +166490,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -166152,14 +166515,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "plexus-sec-dispatcher", "repository": "rhel8-AppStream" @@ -166264,7 +166633,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -166290,14 +166658,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "maven", +"stream": "3.5" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "maven", +"stream": "3.5" +} ], "name": "plexus-utils", "repository": "rhel8-AppStream" @@ -167870,7 +168244,6 @@ null { "action": 4, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -167896,63 +168269,90 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "jcl-over-slf4j", "repository": "rhel8-CRB" }, { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "jul-to-slf4j", "repository": "rhel8-CRB" }, { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "log4j-over-slf4j", "repository": "rhel8-CRB" }, { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "slf4j", "repository": "rhel8-CRB" }, { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "slf4j-ext", "repository": "rhel8-CRB" }, { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "slf4j-jcl", "repository": "rhel8-CRB" }, { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "slf4j-jdk14", "repository": "rhel8-CRB" }, { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "slf4j-log4j12", "repository": "rhel8-CRB" @@ -168597,9 +168997,7 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", -"s390x", "x86_64" ], "id": 4565, @@ -168623,14 +169021,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "pki-deps", +"stream": "10.6" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "pki-deps", +"stream": "10.6" +} ], "name": "velocity", "repository": "rhel8-AppStream" @@ -168647,7 +169051,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -168673,14 +169076,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "pki-deps", +"stream": "10.6" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "pki-deps", +"stream": "10.6" +} ], "name": "velocity-demo", "repository": "rhel8-AppStream" @@ -168697,7 +169106,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -168723,14 +169131,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "pki-deps", +"stream": "10.6" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "pki-deps", +"stream": "10.6" +} ], "name": "velocity-javadoc", "repository": "rhel8-AppStream" @@ -168747,7 +169161,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -168773,14 +169186,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "pki-deps", +"stream": "10.6" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "pki-deps", +"stream": "10.6" +} ], "name": "velocity-manual", "repository": "rhel8-AppStream" @@ -169093,7 +169512,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -169119,14 +169537,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "pki-deps", +"stream": "10.6" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "pki-deps", +"stream": "10.6" +} ], "name": "xalan-j2", "repository": "rhel8-AppStream" @@ -169143,7 +169567,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -169169,14 +169592,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "xalan-j2-demo", "repository": "rhel8-CRB" @@ -169193,7 +169622,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -169219,14 +169647,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "xalan-j2-javadoc", "repository": "rhel8-CRB" @@ -169243,7 +169677,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -169269,14 +169702,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "xalan-j2-manual", "repository": "rhel8-CRB" @@ -169293,7 +169732,6 @@ null { "action": 6, "architectures": [ -"aarch64", "ppc64le", "s390x", "x86_64" @@ -169319,14 +169757,20 @@ null "modulestream_maps": [ { "in_modulestream": null, -"out_modulestream": null +"out_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +} } ], "out_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], "name": "xalan-j2-xsltc", "repository": "rhel8-CRB" @@ -230176,8 +230620,6 @@ null "action": 0, "architectures": [ "aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 6285, @@ -230185,7 +230627,10 @@ null "package": [ { "modulestreams": [ -null +{ +"name": "llvm-toolset", +"stream": "rhel8" +} ], "name": "python3-lldb", "repository": "rhel8-AppStream" @@ -230193,7 +230638,11 @@ null ], "set_id": 9530 }, -"initial_release": null, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, "modulestream_maps": [], "out_packageset": null, "release": { @@ -230215,7 +230664,10 @@ null "package": [ { "modulestreams": [ -null +{ +"name": "llvm-toolset", +"stream": "rhel8" +} ], "name": "compiler-rt", "repository": "rhel8-AppStream" @@ -230223,7 +230675,11 @@ null ], "set_id": 9533 }, -"initial_release": null, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, "modulestream_maps": [], "out_packageset": null, "release": { @@ -230245,7 +230701,10 @@ null "package": [ { "modulestreams": [ -null +{ +"name": "llvm-toolset", +"stream": "rhel8" +} ], "name": "python3-lit", "repository": "rhel8-AppStream" @@ -230253,7 +230712,11 @@ null ], "set_id": 9534 }, -"initial_release": null, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, "modulestream_maps": [], "out_packageset": null, "release": { @@ -253329,7 +253792,14 @@ null "package": [ { "modulestreams": [ -null +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +} ], "name": "php-pecl-xdebug", "repository": "rhel8-AppStream" @@ -253344,7 +253814,17 @@ null }, "modulestream_maps": [ { -"in_modulestream": null, +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, "out_modulestream": null } ], @@ -257092,9 +257572,6 @@ null { "action": 1, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 7052, @@ -257129,9 +257606,6 @@ null { "action": 2, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 7053, @@ -257166,9 +257640,6 @@ null { "action": 1, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 7054, @@ -257177,10 +257648,6 @@ null { "modulestreams": [ { -"name": "maven", -"stream": "3.5" -}, -{ "name": "eclipse", "stream": "rhel8" } @@ -257207,9 +257674,6 @@ null { "action": 2, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 7055, @@ -257218,10 +257682,6 @@ null { "modulestreams": [ { -"name": "maven", -"stream": "3.5" -}, -{ "name": "eclipse", "stream": "rhel8" } @@ -260998,12 +261458,12 @@ null { "modulestreams": [ { -"name": "parfait", -"stream": "0.5" +"name": "javapackages-tools", +"stream": "201801" } ], "name": "log4j12", -"repository": "rhel8-AppStream" +"repository": "rhel8-CRB" } ], "set_id": 10704 @@ -261035,12 +261495,12 @@ null { "modulestreams": [ { -"name": "parfait", -"stream": "0.5" +"name": "javapackages-tools", +"stream": "201801" } ], "name": "log4j12", -"repository": "rhel8-AppStream" +"repository": "rhel8-CRB" } ], "set_id": 18722 @@ -266242,9 +266702,6 @@ null { "action": 1, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 7345, @@ -266279,9 +266736,6 @@ null { "action": 2, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 7346, @@ -266916,9 +267370,6 @@ null { "action": 1, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 7363, @@ -266953,9 +267404,6 @@ null { "action": 2, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 7364, @@ -267064,9 +267512,6 @@ null { "action": 1, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 7367, @@ -267101,9 +267546,6 @@ null { "action": 2, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 7368, @@ -267149,16 +267591,12 @@ null { "modulestreams": [ { -"name": "scala", -"stream": "2.10" -}, -{ -"name": "maven", -"stream": "3.5" +"name": "javapackages-tools", +"stream": "201801" } ], "name": "hawtjni", -"repository": "rhel8-AppStream" +"repository": "rhel8-CRB" } ], "set_id": 10899 @@ -267190,16 +267628,12 @@ null { "modulestreams": [ { -"name": "scala", -"stream": "2.10" -}, -{ -"name": "maven", -"stream": "3.5" +"name": "javapackages-tools", +"stream": "201801" } ], "name": "hawtjni", -"repository": "rhel8-AppStream" +"repository": "rhel8-CRB" } ], "set_id": 18757 @@ -273236,174 +273670,6 @@ null "s390x", "x86_64" ], -"id": 7670, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -{ -"name": "llvm-toolset", -"stream": "rhel8" -} -], -"name": "python3-clang", -"repository": "rhel8-AppStream" -} -], -"set_id": 11193 -}, -"initial_release": { -"major_version": 8, -"minor_version": 5, -"os_name": "RHEL" -}, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "llvm-toolset", -"stream": "rhel8" -}, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "python3-clang", -"repository": "rhel9-AppStream" -} -], -"set_id": 11194 -}, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 6, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 7671, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -{ -"name": "llvm-toolset", -"stream": "rhel8" -} -], -"name": "python3-lit", -"repository": "rhel8-AppStream" -} -], -"set_id": 11195 -}, -"initial_release": { -"major_version": 8, -"minor_version": 5, -"os_name": "RHEL" -}, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "llvm-toolset", -"stream": "rhel8" -}, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "python3-lit", -"repository": "rhel9-AppStream" -} -], -"set_id": 11196 -}, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 6, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 7672, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -{ -"name": "llvm-toolset", -"stream": "rhel8" -} -], -"name": "python3-lldb", -"repository": "rhel8-AppStream" -} -], -"set_id": 11197 -}, -"initial_release": { -"major_version": 8, -"minor_version": 5, -"os_name": "RHEL" -}, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "llvm-toolset", -"stream": "rhel8" -}, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "python3-lldb", -"repository": "rhel9-AppStream" -} -], -"set_id": 11198 -}, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 6, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], "id": 7673, "in_packageset": { "package": [ @@ -302557,18 +302823,18 @@ null "s390x", "x86_64" ], -"id": 8455, +"id": 8457, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bacula-console-bat", +"name": "bmc-snmp-proxy", "repository": "rhel9-AppStream" } ], -"set_id": 12124 +"set_id": 12126 }, "initial_release": { "major_version": 8, @@ -302591,120 +302857,52 @@ null "s390x", "x86_64" ], -"id": 8456, +"id": 8458, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bacula-traymonitor", +"name": "console-setup", +"repository": "rhel9-AppStream" +} +], +"set_id": 12127 +}, +"initial_release": { +"major_version": 8, +"minor_version": 5, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 8459, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "docbook5-style-xsl", "repository": "rhel9-AppStream" } ], -"set_id": 12125 -}, -"initial_release": { -"major_version": 8, -"minor_version": 5, -"os_name": "RHEL" -}, -"modulestream_maps": [], -"out_packageset": null, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 0, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 8457, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "bmc-snmp-proxy", -"repository": "rhel9-AppStream" -} -], -"set_id": 12126 -}, -"initial_release": { -"major_version": 8, -"minor_version": 5, -"os_name": "RHEL" -}, -"modulestream_maps": [], -"out_packageset": null, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 0, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 8458, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "console-setup", -"repository": "rhel9-AppStream" -} -], -"set_id": 12127 -}, -"initial_release": { -"major_version": 8, -"minor_version": 5, -"os_name": "RHEL" -}, -"modulestream_maps": [], -"out_packageset": null, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 0, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 8459, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "docbook5-style-xsl", -"repository": "rhel9-AppStream" -} -], -"set_id": 12128 +"set_id": 12128 }, "initial_release": { "major_version": 8, @@ -343207,6 +343405,10 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" } ], "name": "php-recode", @@ -343281,6 +343483,14 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" } ], "name": "php-xmlrpc", @@ -355787,21 +355997,21 @@ null "s390x", "x86_64" ], -"id": 9997, +"id": 9999, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "parfait", -"stream": "0.5" +"name": "javapackages-tools", +"stream": "201801" } ], "name": "log4j12-javadoc", -"repository": "rhel8-AppStream" +"repository": "rhel8-CRB" } ], -"set_id": 13972 +"set_id": 13973 }, "initial_release": { "major_version": 8, @@ -355817,51 +356027,51 @@ null } }, { -"action": 2, +"action": 1, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 9998, +"id": 10000, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "parfait", -"stream": "0.5" +"name": "javapackages-tools", +"stream": "201801" } ], -"name": "log4j12-javadoc", -"repository": "rhel8-AppStream" +"name": "log4j12", +"repository": "rhel8-CRB" } ], -"set_id": 19041 +"set_id": 13974 }, "initial_release": { "major_version": 8, -"minor_version": 5, +"minor_version": 6, "os_name": "RHEL" }, "modulestream_maps": [], "out_packageset": null, "release": { -"major_version": 8, -"minor_version": 6, +"major_version": 9, +"minor_version": 0, "os_name": "RHEL" } }, { -"action": 1, +"action": 6, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 9999, +"id": 10001, "in_packageset": { "package": [ { @@ -355871,19 +356081,38 @@ null "stream": "201801" } ], -"name": "log4j12-javadoc", +"name": "apache-commons-collections", "repository": "rhel8-CRB" } ], -"set_id": 13973 +"set_id": 15466 }, "initial_release": { "major_version": 8, "minor_version": 6, "os_name": "RHEL" }, -"modulestream_maps": [], -"out_packageset": null, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +}, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "apache-commons-collections", +"repository": "rhel9-CRB" +} +], +"set_id": 15467 +}, "release": { "major_version": 9, "minor_version": 0, @@ -355898,7 +356127,7 @@ null "s390x", "x86_64" ], -"id": 10000, +"id": 10002, "in_packageset": { "package": [ { @@ -355908,11 +356137,11 @@ null "stream": "201801" } ], -"name": "log4j12", +"name": "apache-commons-collections-testframework", "repository": "rhel8-CRB" } ], -"set_id": 13974 +"set_id": 13976 }, "initial_release": { "major_version": 8, @@ -355928,14 +356157,14 @@ null } }, { -"action": 6, +"action": 1, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10001, +"id": 10003, "in_packageset": { "package": [ { @@ -355945,38 +356174,56 @@ null "stream": "201801" } ], -"name": "apache-commons-collections", +"name": "apache-commons-collections-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 15466 +"set_id": 13977 }, "initial_release": { "major_version": 8, "minor_version": 6, "os_name": "RHEL" }, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "javapackages-tools", -"stream": "201801" -}, -"out_modulestream": null +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" } +}, +{ +"action": 1, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" ], -"out_packageset": { +"id": 10004, +"in_packageset": { "package": [ { "modulestreams": [ -null +{ +"name": "javapackages-tools", +"stream": "201801" +} ], -"name": "apache-commons-collections", -"repository": "rhel9-CRB" +"name": "apache-commons-jxpath-javadoc", +"repository": "rhel8-CRB" } ], -"set_id": 15467 +"set_id": 13978 +}, +"initial_release": { +"major_version": 8, +"minor_version": 6, +"os_name": "RHEL" }, +"modulestream_maps": [], +"out_packageset": null, "release": { "major_version": 9, "minor_version": 0, @@ -355991,7 +356238,7 @@ null "s390x", "x86_64" ], -"id": 10002, +"id": 10005, "in_packageset": { "package": [ { @@ -356001,11 +356248,11 @@ null "stream": "201801" } ], -"name": "apache-commons-collections-testframework", +"name": "apache-commons-jxpath", "repository": "rhel8-CRB" } ], -"set_id": 13976 +"set_id": 13979 }, "initial_release": { "major_version": 8, @@ -356028,7 +356275,7 @@ null "s390x", "x86_64" ], -"id": 10003, +"id": 10006, "in_packageset": { "package": [ { @@ -356038,11 +356285,11 @@ null "stream": "201801" } ], -"name": "apache-commons-collections-javadoc", +"name": "byaccj-debugsource", "repository": "rhel8-CRB" } ], -"set_id": 13977 +"set_id": 13980 }, "initial_release": { "major_version": 8, @@ -356065,7 +356312,7 @@ null "s390x", "x86_64" ], -"id": 10004, +"id": 10007, "in_packageset": { "package": [ { @@ -356075,11 +356322,11 @@ null "stream": "201801" } ], -"name": "apache-commons-jxpath-javadoc", +"name": "byaccj-debuginfo", "repository": "rhel8-CRB" } ], -"set_id": 13978 +"set_id": 13981 }, "initial_release": { "major_version": 8, @@ -356102,7 +356349,7 @@ null "s390x", "x86_64" ], -"id": 10005, +"id": 10008, "in_packageset": { "package": [ { @@ -356112,11 +356359,11 @@ null "stream": "201801" } ], -"name": "apache-commons-jxpath", +"name": "felix-osgi-compendium-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 13979 +"set_id": 13982 }, "initial_release": { "major_version": 8, @@ -356139,7 +356386,7 @@ null "s390x", "x86_64" ], -"id": 10006, +"id": 10009, "in_packageset": { "package": [ { @@ -356149,11 +356396,11 @@ null "stream": "201801" } ], -"name": "byaccj-debugsource", +"name": "felix-osgi-core-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 13980 +"set_id": 13983 }, "initial_release": { "major_version": 8, @@ -356176,7 +356423,7 @@ null "s390x", "x86_64" ], -"id": 10007, +"id": 10010, "in_packageset": { "package": [ { @@ -356186,11 +356433,11 @@ null "stream": "201801" } ], -"name": "byaccj-debuginfo", +"name": "felix-osgi-foundation-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 13981 +"set_id": 13984 }, "initial_release": { "major_version": 8, @@ -356213,7 +356460,7 @@ null "s390x", "x86_64" ], -"id": 10008, +"id": 10013, "in_packageset": { "package": [ { @@ -356223,11 +356470,11 @@ null "stream": "201801" } ], -"name": "felix-osgi-compendium-javadoc", +"name": "geronimo-annotation-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 13982 +"set_id": 13986 }, "initial_release": { "major_version": 8, @@ -356250,7 +356497,7 @@ null "s390x", "x86_64" ], -"id": 10009, +"id": 10014, "in_packageset": { "package": [ { @@ -356260,11 +356507,11 @@ null "stream": "201801" } ], -"name": "felix-osgi-core-javadoc", +"name": "geronimo-annotation", "repository": "rhel8-CRB" } ], -"set_id": 13983 +"set_id": 13987 }, "initial_release": { "major_version": 8, @@ -356287,7 +356534,7 @@ null "s390x", "x86_64" ], -"id": 10010, +"id": 10015, "in_packageset": { "package": [ { @@ -356297,11 +356544,11 @@ null "stream": "201801" } ], -"name": "felix-osgi-foundation-javadoc", +"name": "geronimo-jms-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 13984 +"set_id": 13988 }, "initial_release": { "major_version": 8, @@ -356324,7 +356571,7 @@ null "s390x", "x86_64" ], -"id": 10013, +"id": 10016, "in_packageset": { "package": [ { @@ -356334,11 +356581,11 @@ null "stream": "201801" } ], -"name": "geronimo-annotation-javadoc", +"name": "glassfish-annotation-api-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 13986 +"set_id": 13989 }, "initial_release": { "major_version": 8, @@ -356361,7 +356608,7 @@ null "s390x", "x86_64" ], -"id": 10014, +"id": 10017, "in_packageset": { "package": [ { @@ -356371,11 +356618,11 @@ null "stream": "201801" } ], -"name": "geronimo-annotation", +"name": "glassfish-annotation-api", "repository": "rhel8-CRB" } ], -"set_id": 13987 +"set_id": 13990 }, "initial_release": { "major_version": 8, @@ -356398,7 +356645,7 @@ null "s390x", "x86_64" ], -"id": 10015, +"id": 10018, "in_packageset": { "package": [ { @@ -356408,11 +356655,11 @@ null "stream": "201801" } ], -"name": "geronimo-jms-javadoc", +"name": "glassfish-servlet-api-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 13988 +"set_id": 13991 }, "initial_release": { "major_version": 8, @@ -356435,7 +356682,7 @@ null "s390x", "x86_64" ], -"id": 10016, +"id": 10019, "in_packageset": { "package": [ { @@ -356445,11 +356692,11 @@ null "stream": "201801" } ], -"name": "glassfish-annotation-api-javadoc", +"name": "glassfish-servlet-api", "repository": "rhel8-CRB" } ], -"set_id": 13989 +"set_id": 13992 }, "initial_release": { "major_version": 8, @@ -356472,21 +356719,25 @@ null "s390x", "x86_64" ], -"id": 10017, +"id": 10020, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "javapackages-tools", -"stream": "201801" +"name": "maven", +"stream": "3.5" +}, +{ +"name": "scala", +"stream": "2.10" } ], -"name": "glassfish-annotation-api", -"repository": "rhel8-CRB" +"name": "hawtjni-runtime", +"repository": "rhel8-AppStream" } ], -"set_id": 13990 +"set_id": 13993 }, "initial_release": { "major_version": 8, @@ -356502,6 +356753,47 @@ null } }, { +"action": 2, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 10021, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "maven", +"stream": "3.5" +}, +{ +"name": "scala", +"stream": "2.10" +} +], +"name": "hawtjni-runtime", +"repository": "rhel8-AppStream" +} +], +"set_id": 19042 +}, +"initial_release": { +"major_version": 8, +"minor_version": 5, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 6, +"os_name": "RHEL" +} +}, +{ "action": 1, "architectures": [ "aarch64", @@ -356509,7 +356801,7 @@ null "s390x", "x86_64" ], -"id": 10018, +"id": 10026, "in_packageset": { "package": [ { @@ -356519,11 +356811,11 @@ null "stream": "201801" } ], -"name": "glassfish-servlet-api-javadoc", +"name": "hawtjni", "repository": "rhel8-CRB" } ], -"set_id": 13991 +"set_id": 13996 }, "initial_release": { "major_version": 8, @@ -356546,7 +356838,7 @@ null "s390x", "x86_64" ], -"id": 10019, +"id": 10027, "in_packageset": { "package": [ { @@ -356556,11 +356848,11 @@ null "stream": "201801" } ], -"name": "glassfish-servlet-api", +"name": "maven-hawtjni-plugin", "repository": "rhel8-CRB" } ], -"set_id": 13992 +"set_id": 13997 }, "initial_release": { "major_version": 8, @@ -356583,25 +356875,21 @@ null "s390x", "x86_64" ], -"id": 10020, +"id": 10028, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "maven", -"stream": "3.5" -}, -{ -"name": "scala", -"stream": "2.10" +"name": "javapackages-tools", +"stream": "201801" } ], -"name": "hawtjni-runtime", -"repository": "rhel8-AppStream" +"name": "hawtjni-javadoc", +"repository": "rhel8-CRB" } ], -"set_id": 13993 +"set_id": 13998 }, "initial_release": { "major_version": 8, @@ -356617,43 +356905,39 @@ null } }, { -"action": 2, +"action": 1, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10021, +"id": 10029, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "maven", -"stream": "3.5" -}, -{ -"name": "scala", -"stream": "2.10" +"name": "javapackages-tools", +"stream": "201801" } ], "name": "hawtjni-runtime", -"repository": "rhel8-AppStream" +"repository": "rhel8-CRB" } ], -"set_id": 19042 +"set_id": 13999 }, "initial_release": { "major_version": 8, -"minor_version": 5, +"minor_version": 6, "os_name": "RHEL" }, "modulestream_maps": [], "out_packageset": null, "release": { -"major_version": 8, -"minor_version": 6, +"major_version": 9, +"minor_version": 0, "os_name": "RHEL" } }, @@ -356665,7 +356949,7 @@ null "s390x", "x86_64" ], -"id": 10026, +"id": 10030, "in_packageset": { "package": [ { @@ -356675,11 +356959,11 @@ null "stream": "201801" } ], -"name": "hawtjni", +"name": "jakarta-oro-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 13996 +"set_id": 14000 }, "initial_release": { "major_version": 8, @@ -356702,7 +356986,7 @@ null "s390x", "x86_64" ], -"id": 10027, +"id": 10033, "in_packageset": { "package": [ { @@ -356712,11 +356996,11 @@ null "stream": "201801" } ], -"name": "maven-hawtjni-plugin", +"name": "jansi-native-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 13997 +"set_id": 14002 }, "initial_release": { "major_version": 8, @@ -356739,7 +357023,7 @@ null "s390x", "x86_64" ], -"id": 10028, +"id": 10034, "in_packageset": { "package": [ { @@ -356749,11 +357033,11 @@ null "stream": "201801" } ], -"name": "hawtjni-javadoc", +"name": "jansi-native", "repository": "rhel8-CRB" } ], -"set_id": 13998 +"set_id": 14003 }, "initial_release": { "major_version": 8, @@ -356776,7 +357060,7 @@ null "s390x", "x86_64" ], -"id": 10029, +"id": 10035, "in_packageset": { "package": [ { @@ -356786,11 +357070,11 @@ null "stream": "201801" } ], -"name": "hawtjni-runtime", +"name": "java_cup-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 13999 +"set_id": 14004 }, "initial_release": { "major_version": 8, @@ -356813,7 +357097,7 @@ null "s390x", "x86_64" ], -"id": 10030, +"id": 10036, "in_packageset": { "package": [ { @@ -356823,11 +357107,11 @@ null "stream": "201801" } ], -"name": "jakarta-oro-javadoc", +"name": "java_cup-manual", "repository": "rhel8-CRB" } ], -"set_id": 14000 +"set_id": 14005 }, "initial_release": { "major_version": 8, @@ -356850,7 +357134,7 @@ null "s390x", "x86_64" ], -"id": 10033, +"id": 10037, "in_packageset": { "package": [ { @@ -356860,11 +357144,11 @@ null "stream": "201801" } ], -"name": "jansi-native-javadoc", +"name": "jdepend-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14002 +"set_id": 14006 }, "initial_release": { "major_version": 8, @@ -356887,7 +357171,7 @@ null "s390x", "x86_64" ], -"id": 10034, +"id": 10038, "in_packageset": { "package": [ { @@ -356897,11 +357181,11 @@ null "stream": "201801" } ], -"name": "jansi-native", +"name": "jdepend-demo", "repository": "rhel8-CRB" } ], -"set_id": 14003 +"set_id": 14007 }, "initial_release": { "major_version": 8, @@ -356924,7 +357208,7 @@ null "s390x", "x86_64" ], -"id": 10035, +"id": 10039, "in_packageset": { "package": [ { @@ -356934,11 +357218,11 @@ null "stream": "201801" } ], -"name": "java_cup-javadoc", +"name": "jdependency-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14004 +"set_id": 14008 }, "initial_release": { "major_version": 8, @@ -356961,7 +357245,7 @@ null "s390x", "x86_64" ], -"id": 10036, +"id": 10040, "in_packageset": { "package": [ { @@ -356971,11 +357255,11 @@ null "stream": "201801" } ], -"name": "java_cup-manual", +"name": "jdom-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14005 +"set_id": 14009 }, "initial_release": { "major_version": 8, @@ -356998,7 +357282,7 @@ null "s390x", "x86_64" ], -"id": 10037, +"id": 10041, "in_packageset": { "package": [ { @@ -357008,11 +357292,11 @@ null "stream": "201801" } ], -"name": "jdepend-javadoc", +"name": "jdom-demo", "repository": "rhel8-CRB" } ], -"set_id": 14006 +"set_id": 14010 }, "initial_release": { "major_version": 8, @@ -357035,7 +357319,7 @@ null "s390x", "x86_64" ], -"id": 10038, +"id": 10042, "in_packageset": { "package": [ { @@ -357045,11 +357329,11 @@ null "stream": "201801" } ], -"name": "jdepend-demo", +"name": "jdom2-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14007 +"set_id": 14011 }, "initial_release": { "major_version": 8, @@ -357072,7 +357356,7 @@ null "s390x", "x86_64" ], -"id": 10039, +"id": 10043, "in_packageset": { "package": [ { @@ -357082,11 +357366,11 @@ null "stream": "201801" } ], -"name": "jdependency-javadoc", +"name": "jline-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14008 +"set_id": 14012 }, "initial_release": { "major_version": 8, @@ -357109,7 +357393,7 @@ null "s390x", "x86_64" ], -"id": 10040, +"id": 10044, "in_packageset": { "package": [ { @@ -357119,11 +357403,11 @@ null "stream": "201801" } ], -"name": "jdom-javadoc", +"name": "jline", "repository": "rhel8-CRB" } ], -"set_id": 14009 +"set_id": 14013 }, "initial_release": { "major_version": 8, @@ -357146,7 +357430,7 @@ null "s390x", "x86_64" ], -"id": 10041, +"id": 10045, "in_packageset": { "package": [ { @@ -357156,11 +357440,11 @@ null "stream": "201801" } ], -"name": "jdom-demo", +"name": "maven-antrun-plugin-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14010 +"set_id": 14014 }, "initial_release": { "major_version": 8, @@ -357183,7 +357467,7 @@ null "s390x", "x86_64" ], -"id": 10042, +"id": 10046, "in_packageset": { "package": [ { @@ -357193,11 +357477,11 @@ null "stream": "201801" } ], -"name": "jdom2-javadoc", +"name": "maven-assembly-plugin-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14011 +"set_id": 14015 }, "initial_release": { "major_version": 8, @@ -357220,7 +357504,7 @@ null "s390x", "x86_64" ], -"id": 10043, +"id": 10047, "in_packageset": { "package": [ { @@ -357230,11 +357514,11 @@ null "stream": "201801" } ], -"name": "jline-javadoc", +"name": "maven-dependency-analyzer-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14012 +"set_id": 14016 }, "initial_release": { "major_version": 8, @@ -357257,7 +357541,7 @@ null "s390x", "x86_64" ], -"id": 10044, +"id": 10048, "in_packageset": { "package": [ { @@ -357267,11 +357551,11 @@ null "stream": "201801" } ], -"name": "jline", +"name": "maven-dependency-plugin-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14013 +"set_id": 14017 }, "initial_release": { "major_version": 8, @@ -357294,7 +357578,7 @@ null "s390x", "x86_64" ], -"id": 10045, +"id": 10049, "in_packageset": { "package": [ { @@ -357304,11 +357588,11 @@ null "stream": "201801" } ], -"name": "maven-antrun-plugin-javadoc", +"name": "maven-shade-plugin-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14014 +"set_id": 14018 }, "initial_release": { "major_version": 8, @@ -357331,7 +357615,7 @@ null "s390x", "x86_64" ], -"id": 10046, +"id": 10050, "in_packageset": { "package": [ { @@ -357341,11 +357625,11 @@ null "stream": "201801" } ], -"name": "maven-assembly-plugin-javadoc", +"name": "modello-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14015 +"set_id": 14019 }, "initial_release": { "major_version": 8, @@ -357368,7 +357652,7 @@ null "s390x", "x86_64" ], -"id": 10047, +"id": 10051, "in_packageset": { "package": [ { @@ -357378,11 +357662,11 @@ null "stream": "201801" } ], -"name": "maven-dependency-analyzer-javadoc", +"name": "munge-maven-plugin-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14016 +"set_id": 14020 }, "initial_release": { "major_version": 8, @@ -357405,7 +357689,7 @@ null "s390x", "x86_64" ], -"id": 10048, +"id": 10052, "in_packageset": { "package": [ { @@ -357415,11 +357699,11 @@ null "stream": "201801" } ], -"name": "maven-dependency-plugin-javadoc", +"name": "plexus-ant-factory-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14017 +"set_id": 14021 }, "initial_release": { "major_version": 8, @@ -357442,7 +357726,7 @@ null "s390x", "x86_64" ], -"id": 10049, +"id": 10053, "in_packageset": { "package": [ { @@ -357452,11 +357736,11 @@ null "stream": "201801" } ], -"name": "maven-shade-plugin-javadoc", +"name": "plexus-bsh-factory-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14018 +"set_id": 14022 }, "initial_release": { "major_version": 8, @@ -357479,7 +357763,7 @@ null "s390x", "x86_64" ], -"id": 10050, +"id": 10054, "in_packageset": { "package": [ { @@ -357489,11 +357773,11 @@ null "stream": "201801" } ], -"name": "modello-javadoc", +"name": "plexus-cli-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14019 +"set_id": 14023 }, "initial_release": { "major_version": 8, @@ -357516,7 +357800,7 @@ null "s390x", "x86_64" ], -"id": 10051, +"id": 10055, "in_packageset": { "package": [ { @@ -357526,11 +357810,11 @@ null "stream": "201801" } ], -"name": "munge-maven-plugin-javadoc", +"name": "powermock-api-easymock", "repository": "rhel8-CRB" } ], -"set_id": 14020 +"set_id": 14024 }, "initial_release": { "major_version": 8, @@ -357553,7 +357837,7 @@ null "s390x", "x86_64" ], -"id": 10052, +"id": 10056, "in_packageset": { "package": [ { @@ -357563,11 +357847,11 @@ null "stream": "201801" } ], -"name": "plexus-ant-factory-javadoc", +"name": "powermock-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14021 +"set_id": 14025 }, "initial_release": { "major_version": 8, @@ -357590,7 +357874,7 @@ null "s390x", "x86_64" ], -"id": 10053, +"id": 10057, "in_packageset": { "package": [ { @@ -357600,11 +357884,11 @@ null "stream": "201801" } ], -"name": "plexus-bsh-factory-javadoc", +"name": "powermock-reflect", "repository": "rhel8-CRB" } ], -"set_id": 14022 +"set_id": 14026 }, "initial_release": { "major_version": 8, @@ -357627,7 +357911,7 @@ null "s390x", "x86_64" ], -"id": 10054, +"id": 10058, "in_packageset": { "package": [ { @@ -357637,11 +357921,11 @@ null "stream": "201801" } ], -"name": "plexus-cli-javadoc", +"name": "powermock-junit4", "repository": "rhel8-CRB" } ], -"set_id": 14023 +"set_id": 14027 }, "initial_release": { "major_version": 8, @@ -357664,7 +357948,7 @@ null "s390x", "x86_64" ], -"id": 10055, +"id": 10059, "in_packageset": { "package": [ { @@ -357674,11 +357958,11 @@ null "stream": "201801" } ], -"name": "powermock-api-easymock", +"name": "powermock-core", "repository": "rhel8-CRB" } ], -"set_id": 14024 +"set_id": 14028 }, "initial_release": { "major_version": 8, @@ -357701,7 +357985,7 @@ null "s390x", "x86_64" ], -"id": 10056, +"id": 10060, "in_packageset": { "package": [ { @@ -357711,11 +357995,11 @@ null "stream": "201801" } ], -"name": "powermock-javadoc", +"name": "powermock-api-mockito", "repository": "rhel8-CRB" } ], -"set_id": 14025 +"set_id": 14029 }, "initial_release": { "major_version": 8, @@ -357738,7 +358022,7 @@ null "s390x", "x86_64" ], -"id": 10057, +"id": 10061, "in_packageset": { "package": [ { @@ -357748,11 +358032,11 @@ null "stream": "201801" } ], -"name": "powermock-reflect", +"name": "powermock-api-support", "repository": "rhel8-CRB" } ], -"set_id": 14026 +"set_id": 14030 }, "initial_release": { "major_version": 8, @@ -357775,7 +358059,7 @@ null "s390x", "x86_64" ], -"id": 10058, +"id": 10062, "in_packageset": { "package": [ { @@ -357785,11 +358069,11 @@ null "stream": "201801" } ], -"name": "powermock-junit4", +"name": "powermock-testng", "repository": "rhel8-CRB" } ], -"set_id": 14027 +"set_id": 14031 }, "initial_release": { "major_version": 8, @@ -357812,7 +358096,7 @@ null "s390x", "x86_64" ], -"id": 10059, +"id": 10063, "in_packageset": { "package": [ { @@ -357822,11 +358106,11 @@ null "stream": "201801" } ], -"name": "powermock-core", +"name": "powermock-common", "repository": "rhel8-CRB" } ], -"set_id": 14028 +"set_id": 14032 }, "initial_release": { "major_version": 8, @@ -357849,7 +358133,7 @@ null "s390x", "x86_64" ], -"id": 10060, +"id": 10064, "in_packageset": { "package": [ { @@ -357859,11 +358143,11 @@ null "stream": "201801" } ], -"name": "powermock-api-mockito", +"name": "sisu-mojos-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14029 +"set_id": 14033 }, "initial_release": { "major_version": 8, @@ -357886,7 +358170,7 @@ null "s390x", "x86_64" ], -"id": 10061, +"id": 10065, "in_packageset": { "package": [ { @@ -357896,11 +358180,11 @@ null "stream": "201801" } ], -"name": "powermock-api-support", +"name": "testng-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14030 +"set_id": 14034 }, "initial_release": { "major_version": 8, @@ -357923,7 +358207,7 @@ null "s390x", "x86_64" ], -"id": 10062, +"id": 10066, "in_packageset": { "package": [ { @@ -357933,11 +358217,11 @@ null "stream": "201801" } ], -"name": "powermock-testng", +"name": "jflex-javadoc", "repository": "rhel8-CRB" } ], -"set_id": 14031 +"set_id": 14035 }, "initial_release": { "major_version": 8, @@ -357953,28 +358237,25 @@ null } }, { -"action": 1, +"action": 0, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10063, +"id": 10067, "in_packageset": { "package": [ { "modulestreams": [ -{ -"name": "javapackages-tools", -"stream": "201801" -} +null ], -"name": "powermock-common", -"repository": "rhel8-CRB" +"name": "exfatprogs", +"repository": "rhel9-BaseOS" } ], -"set_id": 14032 +"set_id": 14044 }, "initial_release": { "major_version": 8, @@ -357997,21 +358278,18 @@ null "s390x", "x86_64" ], -"id": 10064, +"id": 10068, "in_packageset": { "package": [ { "modulestreams": [ -{ -"name": "javapackages-tools", -"stream": "201801" -} +null ], -"name": "sisu-mojos-javadoc", -"repository": "rhel8-CRB" +"name": "trousers-lib", +"repository": "rhel8-BaseOS" } ], -"set_id": 14033 +"set_id": 14045 }, "initial_release": { "major_version": 8, @@ -358027,73 +358305,83 @@ null } }, { -"action": 1, +"action": 2, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10065, +"id": 10069, "in_packageset": { "package": [ { "modulestreams": [ -{ -"name": "javapackages-tools", -"stream": "201801" -} +null ], -"name": "testng-javadoc", -"repository": "rhel8-CRB" +"name": "trousers-lib", +"repository": "rhel8-BaseOS" } ], -"set_id": 14034 +"set_id": 19043 }, "initial_release": { "major_version": 8, -"minor_version": 6, +"minor_version": 5, "os_name": "RHEL" }, "modulestream_maps": [], "out_packageset": null, "release": { -"major_version": 9, -"minor_version": 0, +"major_version": 8, +"minor_version": 6, "os_name": "RHEL" } }, { -"action": 1, +"action": 6, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10066, +"id": 10070, "in_packageset": { "package": [ { "modulestreams": [ -{ -"name": "javapackages-tools", -"stream": "201801" -} +null ], -"name": "jflex-javadoc", -"repository": "rhel8-CRB" +"name": "rasdaemon", +"repository": "rhel8-BaseOS" } ], -"set_id": 14035 +"set_id": 14057 }, "initial_release": { "major_version": 8, "minor_version": 6, "os_name": "RHEL" }, -"modulestream_maps": [], -"out_packageset": null, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "rasdaemon", +"repository": "rhel9-AppStream" +} +], +"set_id": 14058 +}, "release": { "major_version": 9, "minor_version": 0, @@ -358101,29 +358389,29 @@ null } }, { -"action": 0, +"action": 1, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10067, +"id": 10071, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "exfatprogs", -"repository": "rhel9-BaseOS" +"name": "bpg-algeti-fonts", +"repository": "rhel8-AppStream" } ], -"set_id": 14044 +"set_id": 14059 }, "initial_release": { "major_version": 8, -"minor_version": 6, +"minor_version": 5, "os_name": "RHEL" }, "modulestream_maps": [], @@ -358135,59 +358423,59 @@ null } }, { -"action": 1, +"action": 2, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10068, +"id": 10072, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "trousers-lib", -"repository": "rhel8-BaseOS" +"name": "bpg-algeti-fonts", +"repository": "rhel8-AppStream" } ], -"set_id": 14045 +"set_id": 19044 }, "initial_release": { "major_version": 8, -"minor_version": 6, +"minor_version": 4, "os_name": "RHEL" }, "modulestream_maps": [], "out_packageset": null, "release": { -"major_version": 9, -"minor_version": 0, +"major_version": 8, +"minor_version": 5, "os_name": "RHEL" } }, { -"action": 2, +"action": 1, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10069, +"id": 10073, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "trousers-lib", -"repository": "rhel8-BaseOS" +"name": "bpg-chveulebrivi-fonts", +"repository": "rhel8-AppStream" } ], -"set_id": 19043 +"set_id": 14060 }, "initial_release": { "major_version": 8, @@ -358197,58 +358485,42 @@ null "modulestream_maps": [], "out_packageset": null, "release": { -"major_version": 8, -"minor_version": 6, +"major_version": 9, +"minor_version": 0, "os_name": "RHEL" } }, { -"action": 6, +"action": 2, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10070, +"id": 10074, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "rasdaemon", -"repository": "rhel8-BaseOS" +"name": "bpg-chveulebrivi-fonts", +"repository": "rhel8-AppStream" } ], -"set_id": 14057 +"set_id": 19045 }, "initial_release": { "major_version": 8, -"minor_version": 6, +"minor_version": 4, "os_name": "RHEL" }, -"modulestream_maps": [ -{ -"in_modulestream": null, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "rasdaemon", -"repository": "rhel9-AppStream" -} -], -"set_id": 14058 -}, +"modulestream_maps": [], +"out_packageset": null, "release": { -"major_version": 9, -"minor_version": 0, +"major_version": 8, +"minor_version": 5, "os_name": "RHEL" } }, @@ -358260,18 +358532,18 @@ null "s390x", "x86_64" ], -"id": 10071, +"id": 10075, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-algeti-fonts", +"name": "bpg-classic-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14059 +"set_id": 14061 }, "initial_release": { "major_version": 8, @@ -358294,18 +358566,18 @@ null "s390x", "x86_64" ], -"id": 10072, +"id": 10076, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-algeti-fonts", +"name": "bpg-classic-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19044 +"set_id": 19046 }, "initial_release": { "major_version": 8, @@ -358328,18 +358600,18 @@ null "s390x", "x86_64" ], -"id": 10073, +"id": 10077, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-chveulebrivi-fonts", +"name": "bpg-courier-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14060 +"set_id": 14062 }, "initial_release": { "major_version": 8, @@ -358362,18 +358634,18 @@ null "s390x", "x86_64" ], -"id": 10074, +"id": 10078, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-chveulebrivi-fonts", +"name": "bpg-courier-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19045 +"set_id": 19047 }, "initial_release": { "major_version": 8, @@ -358396,18 +358668,18 @@ null "s390x", "x86_64" ], -"id": 10075, +"id": 10079, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-classic-fonts", +"name": "bpg-courier-s-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14061 +"set_id": 14063 }, "initial_release": { "major_version": 8, @@ -358430,18 +358702,18 @@ null "s390x", "x86_64" ], -"id": 10076, +"id": 10080, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-classic-fonts", +"name": "bpg-courier-s-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19046 +"set_id": 19048 }, "initial_release": { "major_version": 8, @@ -358464,18 +358736,18 @@ null "s390x", "x86_64" ], -"id": 10077, +"id": 10081, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-courier-fonts", +"name": "bpg-dedaena-block-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14062 +"set_id": 14064 }, "initial_release": { "major_version": 8, @@ -358498,18 +358770,18 @@ null "s390x", "x86_64" ], -"id": 10078, +"id": 10082, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-courier-fonts", +"name": "bpg-dedaena-block-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19047 +"set_id": 19049 }, "initial_release": { "major_version": 8, @@ -358532,18 +358804,18 @@ null "s390x", "x86_64" ], -"id": 10079, +"id": 10083, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-courier-s-fonts", +"name": "bpg-dejavu-sans-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14063 +"set_id": 14065 }, "initial_release": { "major_version": 8, @@ -358566,18 +358838,18 @@ null "s390x", "x86_64" ], -"id": 10080, +"id": 10084, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-courier-s-fonts", +"name": "bpg-dejavu-sans-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19048 +"set_id": 19050 }, "initial_release": { "major_version": 8, @@ -358600,18 +358872,18 @@ null "s390x", "x86_64" ], -"id": 10081, +"id": 10085, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-dedaena-block-fonts", +"name": "bpg-elite-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14064 +"set_id": 14066 }, "initial_release": { "major_version": 8, @@ -358634,18 +358906,18 @@ null "s390x", "x86_64" ], -"id": 10082, +"id": 10086, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-dedaena-block-fonts", +"name": "bpg-elite-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19049 +"set_id": 19051 }, "initial_release": { "major_version": 8, @@ -358668,18 +358940,18 @@ null "s390x", "x86_64" ], -"id": 10083, +"id": 10087, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-dejavu-sans-fonts", +"name": "bpg-excelsior-caps-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14065 +"set_id": 14067 }, "initial_release": { "major_version": 8, @@ -358702,18 +358974,18 @@ null "s390x", "x86_64" ], -"id": 10084, +"id": 10088, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-dejavu-sans-fonts", +"name": "bpg-excelsior-caps-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19050 +"set_id": 19052 }, "initial_release": { "major_version": 8, @@ -358736,18 +359008,18 @@ null "s390x", "x86_64" ], -"id": 10085, +"id": 10089, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-elite-fonts", +"name": "bpg-excelsior-condenced-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14066 +"set_id": 14068 }, "initial_release": { "major_version": 8, @@ -358770,18 +359042,18 @@ null "s390x", "x86_64" ], -"id": 10086, +"id": 10090, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-elite-fonts", +"name": "bpg-excelsior-condenced-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19051 +"set_id": 19053 }, "initial_release": { "major_version": 8, @@ -358804,18 +359076,18 @@ null "s390x", "x86_64" ], -"id": 10087, +"id": 10091, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-excelsior-caps-fonts", +"name": "bpg-excelsior-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14067 +"set_id": 14069 }, "initial_release": { "major_version": 8, @@ -358838,18 +359110,18 @@ null "s390x", "x86_64" ], -"id": 10088, +"id": 10092, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-excelsior-caps-fonts", +"name": "bpg-excelsior-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19052 +"set_id": 19054 }, "initial_release": { "major_version": 8, @@ -358872,18 +359144,18 @@ null "s390x", "x86_64" ], -"id": 10089, +"id": 10093, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-excelsior-condenced-fonts", +"name": "bpg-fonts-common", "repository": "rhel8-AppStream" } ], -"set_id": 14068 +"set_id": 14070 }, "initial_release": { "major_version": 8, @@ -358906,18 +359178,18 @@ null "s390x", "x86_64" ], -"id": 10090, +"id": 10094, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-excelsior-condenced-fonts", +"name": "bpg-fonts-common", "repository": "rhel8-AppStream" } ], -"set_id": 19053 +"set_id": 19055 }, "initial_release": { "major_version": 8, @@ -358940,18 +359212,18 @@ null "s390x", "x86_64" ], -"id": 10091, +"id": 10095, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-excelsior-fonts", +"name": "bpg-glaho-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14069 +"set_id": 14071 }, "initial_release": { "major_version": 8, @@ -358974,18 +359246,18 @@ null "s390x", "x86_64" ], -"id": 10092, +"id": 10096, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-excelsior-fonts", +"name": "bpg-glaho-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19054 +"set_id": 19056 }, "initial_release": { "major_version": 8, @@ -359008,18 +359280,18 @@ null "s390x", "x86_64" ], -"id": 10093, +"id": 10097, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-fonts-common", +"name": "bpg-gorda-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14070 +"set_id": 14072 }, "initial_release": { "major_version": 8, @@ -359042,18 +359314,18 @@ null "s390x", "x86_64" ], -"id": 10094, +"id": 10098, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-fonts-common", +"name": "bpg-gorda-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19055 +"set_id": 19057 }, "initial_release": { "major_version": 8, @@ -359076,18 +359348,18 @@ null "s390x", "x86_64" ], -"id": 10095, +"id": 10099, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-glaho-fonts", +"name": "bpg-ingiri-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14071 +"set_id": 14073 }, "initial_release": { "major_version": 8, @@ -359110,18 +359382,18 @@ null "s390x", "x86_64" ], -"id": 10096, +"id": 10100, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-glaho-fonts", +"name": "bpg-ingiri-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19056 +"set_id": 19058 }, "initial_release": { "major_version": 8, @@ -359144,18 +359416,18 @@ null "s390x", "x86_64" ], -"id": 10097, +"id": 10101, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-gorda-fonts", +"name": "bpg-irubaqidze-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14072 +"set_id": 14074 }, "initial_release": { "major_version": 8, @@ -359178,18 +359450,18 @@ null "s390x", "x86_64" ], -"id": 10098, +"id": 10102, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-gorda-fonts", +"name": "bpg-irubaqidze-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19057 +"set_id": 19059 }, "initial_release": { "major_version": 8, @@ -359212,18 +359484,18 @@ null "s390x", "x86_64" ], -"id": 10099, +"id": 10103, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-ingiri-fonts", +"name": "bpg-mikhail-stephan-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14073 +"set_id": 14075 }, "initial_release": { "major_version": 8, @@ -359246,18 +359518,18 @@ null "s390x", "x86_64" ], -"id": 10100, +"id": 10104, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-ingiri-fonts", +"name": "bpg-mikhail-stephan-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19058 +"set_id": 19060 }, "initial_release": { "major_version": 8, @@ -359280,18 +359552,18 @@ null "s390x", "x86_64" ], -"id": 10101, +"id": 10105, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-irubaqidze-fonts", +"name": "bpg-mrgvlovani-caps-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14074 +"set_id": 14076 }, "initial_release": { "major_version": 8, @@ -359314,18 +359586,18 @@ null "s390x", "x86_64" ], -"id": 10102, +"id": 10106, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-irubaqidze-fonts", +"name": "bpg-mrgvlovani-caps-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19059 +"set_id": 19061 }, "initial_release": { "major_version": 8, @@ -359348,18 +359620,18 @@ null "s390x", "x86_64" ], -"id": 10103, +"id": 10107, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-mikhail-stephan-fonts", +"name": "bpg-mrgvlovani-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14075 +"set_id": 14077 }, "initial_release": { "major_version": 8, @@ -359382,18 +359654,18 @@ null "s390x", "x86_64" ], -"id": 10104, +"id": 10108, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-mikhail-stephan-fonts", +"name": "bpg-mrgvlovani-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19060 +"set_id": 19062 }, "initial_release": { "major_version": 8, @@ -359416,18 +359688,18 @@ null "s390x", "x86_64" ], -"id": 10105, +"id": 10109, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-mrgvlovani-caps-fonts", +"name": "bpg-nateli-caps-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14076 +"set_id": 14078 }, "initial_release": { "major_version": 8, @@ -359450,18 +359722,18 @@ null "s390x", "x86_64" ], -"id": 10106, +"id": 10110, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-mrgvlovani-caps-fonts", +"name": "bpg-nateli-caps-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19061 +"set_id": 19063 }, "initial_release": { "major_version": 8, @@ -359484,18 +359756,18 @@ null "s390x", "x86_64" ], -"id": 10107, +"id": 10111, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-mrgvlovani-fonts", +"name": "bpg-nateli-condenced-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14077 +"set_id": 14079 }, "initial_release": { "major_version": 8, @@ -359518,18 +359790,18 @@ null "s390x", "x86_64" ], -"id": 10108, +"id": 10112, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-mrgvlovani-fonts", +"name": "bpg-nateli-condenced-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19062 +"set_id": 19064 }, "initial_release": { "major_version": 8, @@ -359552,18 +359824,18 @@ null "s390x", "x86_64" ], -"id": 10109, +"id": 10113, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-nateli-caps-fonts", +"name": "bpg-nateli-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14078 +"set_id": 14080 }, "initial_release": { "major_version": 8, @@ -359586,18 +359858,18 @@ null "s390x", "x86_64" ], -"id": 10110, +"id": 10114, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-nateli-caps-fonts", +"name": "bpg-nateli-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19063 +"set_id": 19065 }, "initial_release": { "major_version": 8, @@ -359620,18 +359892,18 @@ null "s390x", "x86_64" ], -"id": 10111, +"id": 10115, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-nateli-condenced-fonts", +"name": "bpg-nino-medium-cond-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14079 +"set_id": 14081 }, "initial_release": { "major_version": 8, @@ -359654,18 +359926,18 @@ null "s390x", "x86_64" ], -"id": 10112, +"id": 10116, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-nateli-condenced-fonts", +"name": "bpg-nino-medium-cond-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19064 +"set_id": 19066 }, "initial_release": { "major_version": 8, @@ -359688,18 +359960,18 @@ null "s390x", "x86_64" ], -"id": 10113, +"id": 10117, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-nateli-fonts", +"name": "bpg-nino-medium-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14080 +"set_id": 14082 }, "initial_release": { "major_version": 8, @@ -359722,18 +359994,18 @@ null "s390x", "x86_64" ], -"id": 10114, +"id": 10118, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-nateli-fonts", +"name": "bpg-nino-medium-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19065 +"set_id": 19067 }, "initial_release": { "major_version": 8, @@ -359756,18 +360028,18 @@ null "s390x", "x86_64" ], -"id": 10115, +"id": 10119, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-nino-medium-cond-fonts", +"name": "bpg-sans-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14081 +"set_id": 14083 }, "initial_release": { "major_version": 8, @@ -359790,18 +360062,18 @@ null "s390x", "x86_64" ], -"id": 10116, +"id": 10120, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-nino-medium-cond-fonts", +"name": "bpg-sans-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19066 +"set_id": 19068 }, "initial_release": { "major_version": 8, @@ -359824,18 +360096,18 @@ null "s390x", "x86_64" ], -"id": 10117, +"id": 10121, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-nino-medium-fonts", +"name": "bpg-sans-medium-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14082 +"set_id": 14084 }, "initial_release": { "major_version": 8, @@ -359858,18 +360130,18 @@ null "s390x", "x86_64" ], -"id": 10118, +"id": 10122, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-nino-medium-fonts", +"name": "bpg-sans-medium-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19067 +"set_id": 19069 }, "initial_release": { "major_version": 8, @@ -359892,18 +360164,18 @@ null "s390x", "x86_64" ], -"id": 10119, +"id": 10123, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-sans-fonts", +"name": "bpg-sans-modern-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14083 +"set_id": 14085 }, "initial_release": { "major_version": 8, @@ -359926,18 +360198,18 @@ null "s390x", "x86_64" ], -"id": 10120, +"id": 10124, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-sans-fonts", +"name": "bpg-sans-modern-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19068 +"set_id": 19070 }, "initial_release": { "major_version": 8, @@ -359960,18 +360232,18 @@ null "s390x", "x86_64" ], -"id": 10121, +"id": 10125, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-sans-medium-fonts", +"name": "bpg-sans-regular-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14084 +"set_id": 14086 }, "initial_release": { "major_version": 8, @@ -359994,18 +360266,18 @@ null "s390x", "x86_64" ], -"id": 10122, +"id": 10126, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-sans-medium-fonts", +"name": "bpg-sans-regular-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19069 +"set_id": 19071 }, "initial_release": { "major_version": 8, @@ -360028,18 +360300,18 @@ null "s390x", "x86_64" ], -"id": 10123, +"id": 10127, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-sans-modern-fonts", +"name": "bpg-serif-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14085 +"set_id": 14087 }, "initial_release": { "major_version": 8, @@ -360062,18 +360334,18 @@ null "s390x", "x86_64" ], -"id": 10124, +"id": 10128, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-sans-modern-fonts", +"name": "bpg-serif-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19070 +"set_id": 19072 }, "initial_release": { "major_version": 8, @@ -360096,18 +360368,18 @@ null "s390x", "x86_64" ], -"id": 10125, +"id": 10129, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-sans-regular-fonts", +"name": "bpg-serif-modern-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14086 +"set_id": 14088 }, "initial_release": { "major_version": 8, @@ -360130,18 +360402,18 @@ null "s390x", "x86_64" ], -"id": 10126, +"id": 10130, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-sans-regular-fonts", +"name": "bpg-serif-modern-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19071 +"set_id": 19073 }, "initial_release": { "major_version": 8, @@ -360164,18 +360436,18 @@ null "s390x", "x86_64" ], -"id": 10127, +"id": 10131, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-serif-fonts", +"name": "bpg-ucnobi-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14087 +"set_id": 14089 }, "initial_release": { "major_version": 8, @@ -360198,18 +360470,18 @@ null "s390x", "x86_64" ], -"id": 10128, +"id": 10132, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-serif-fonts", +"name": "bpg-ucnobi-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19072 +"set_id": 19074 }, "initial_release": { "major_version": 8, @@ -360232,18 +360504,18 @@ null "s390x", "x86_64" ], -"id": 10129, +"id": 10133, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-serif-modern-fonts", +"name": "fonts-tweak-tool", "repository": "rhel8-AppStream" } ], -"set_id": 14088 +"set_id": 14090 }, "initial_release": { "major_version": 8, @@ -360266,18 +360538,18 @@ null "s390x", "x86_64" ], -"id": 10130, +"id": 10134, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-serif-modern-fonts", +"name": "fonts-tweak-tool", "repository": "rhel8-AppStream" } ], -"set_id": 19073 +"set_id": 19075 }, "initial_release": { "major_version": 8, @@ -360300,18 +360572,18 @@ null "s390x", "x86_64" ], -"id": 10131, +"id": 10135, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-ucnobi-fonts", +"name": "gnu-free-fonts-common", "repository": "rhel8-AppStream" } ], -"set_id": 14089 +"set_id": 14091 }, "initial_release": { "major_version": 8, @@ -360334,18 +360606,18 @@ null "s390x", "x86_64" ], -"id": 10132, +"id": 10136, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "bpg-ucnobi-fonts", +"name": "gnu-free-fonts-common", "repository": "rhel8-AppStream" } ], -"set_id": 19074 +"set_id": 19076 }, "initial_release": { "major_version": 8, @@ -360368,18 +360640,18 @@ null "s390x", "x86_64" ], -"id": 10133, +"id": 10137, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "fonts-tweak-tool", +"name": "gnu-free-mono-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14090 +"set_id": 14092 }, "initial_release": { "major_version": 8, @@ -360402,18 +360674,18 @@ null "s390x", "x86_64" ], -"id": 10134, +"id": 10138, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "fonts-tweak-tool", +"name": "gnu-free-mono-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19075 +"set_id": 19077 }, "initial_release": { "major_version": 8, @@ -360436,18 +360708,18 @@ null "s390x", "x86_64" ], -"id": 10135, +"id": 10139, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "gnu-free-fonts-common", +"name": "gnu-free-sans-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14091 +"set_id": 14093 }, "initial_release": { "major_version": 8, @@ -360470,18 +360742,18 @@ null "s390x", "x86_64" ], -"id": 10136, +"id": 10140, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "gnu-free-fonts-common", +"name": "gnu-free-sans-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19076 +"set_id": 19078 }, "initial_release": { "major_version": 8, @@ -360504,18 +360776,18 @@ null "s390x", "x86_64" ], -"id": 10137, +"id": 10141, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "gnu-free-mono-fonts", +"name": "gnu-free-serif-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14092 +"set_id": 14094 }, "initial_release": { "major_version": 8, @@ -360538,18 +360810,18 @@ null "s390x", "x86_64" ], -"id": 10138, +"id": 10142, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "gnu-free-mono-fonts", +"name": "gnu-free-serif-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19077 +"set_id": 19079 }, "initial_release": { "major_version": 8, @@ -360572,18 +360844,18 @@ null "s390x", "x86_64" ], -"id": 10139, +"id": 10145, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "gnu-free-sans-fonts", +"name": "google-noto-sans-syriac-estrangela-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14093 +"set_id": 14419 }, "initial_release": { "major_version": 8, @@ -360599,138 +360871,138 @@ null } }, { -"action": 2, +"action": 1, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10140, +"id": 10147, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "gnu-free-sans-fonts", +"name": "google-noto-sans-tibetan-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19078 +"set_id": 14097 }, "initial_release": { "major_version": 8, -"minor_version": 4, +"minor_version": 5, "os_name": "RHEL" }, "modulestream_maps": [], "out_packageset": null, "release": { -"major_version": 8, -"minor_version": 5, +"major_version": 9, +"minor_version": 0, "os_name": "RHEL" } }, { -"action": 1, +"action": 2, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10141, +"id": 10148, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "gnu-free-serif-fonts", +"name": "google-noto-sans-tibetan-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14094 +"set_id": 19081 }, "initial_release": { "major_version": 8, -"minor_version": 5, +"minor_version": 4, "os_name": "RHEL" }, "modulestream_maps": [], "out_packageset": null, "release": { -"major_version": 9, -"minor_version": 0, +"major_version": 8, +"minor_version": 5, "os_name": "RHEL" } }, { -"action": 2, +"action": 1, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10142, +"id": 10149, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "gnu-free-serif-fonts", +"name": "google-noto-sans-ui-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19079 +"set_id": 14098 }, "initial_release": { "major_version": 8, -"minor_version": 4, +"minor_version": 5, "os_name": "RHEL" }, "modulestream_maps": [], "out_packageset": null, "release": { -"major_version": 8, -"minor_version": 5, +"major_version": 9, +"minor_version": 0, "os_name": "RHEL" } }, { -"action": 1, +"action": 2, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 10145, +"id": 10150, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "google-noto-sans-syriac-estrangela-fonts", +"name": "google-noto-sans-ui-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14419 +"set_id": 19082 }, "initial_release": { "major_version": 8, -"minor_version": 5, +"minor_version": 4, "os_name": "RHEL" }, "modulestream_maps": [], "out_packageset": null, "release": { -"major_version": 9, -"minor_version": 0, +"major_version": 8, +"minor_version": 5, "os_name": "RHEL" } }, @@ -360742,18 +361014,18 @@ null "s390x", "x86_64" ], -"id": 10147, +"id": 10151, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "google-noto-sans-tibetan-fonts", +"name": "hyphen-fo", "repository": "rhel8-AppStream" } ], -"set_id": 14097 +"set_id": 14099 }, "initial_release": { "major_version": 8, @@ -360776,18 +361048,18 @@ null "s390x", "x86_64" ], -"id": 10148, +"id": 10152, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "google-noto-sans-tibetan-fonts", +"name": "hyphen-fo", "repository": "rhel8-AppStream" } ], -"set_id": 19081 +"set_id": 19083 }, "initial_release": { "major_version": 8, @@ -360810,18 +361082,18 @@ null "s390x", "x86_64" ], -"id": 10149, +"id": 10153, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "google-noto-sans-ui-fonts", +"name": "hyphen-grc", "repository": "rhel8-AppStream" } ], -"set_id": 14098 +"set_id": 14100 }, "initial_release": { "major_version": 8, @@ -360844,18 +361116,18 @@ null "s390x", "x86_64" ], -"id": 10150, +"id": 10154, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "google-noto-sans-ui-fonts", +"name": "hyphen-grc", "repository": "rhel8-AppStream" } ], -"set_id": 19082 +"set_id": 19084 }, "initial_release": { "major_version": 8, @@ -360878,18 +361150,18 @@ null "s390x", "x86_64" ], -"id": 10151, +"id": 10155, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-fo", +"name": "hyphen-hsb", "repository": "rhel8-AppStream" } ], -"set_id": 14099 +"set_id": 14101 }, "initial_release": { "major_version": 8, @@ -360912,18 +361184,18 @@ null "s390x", "x86_64" ], -"id": 10152, +"id": 10156, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-fo", +"name": "hyphen-hsb", "repository": "rhel8-AppStream" } ], -"set_id": 19083 +"set_id": 19085 }, "initial_release": { "major_version": 8, @@ -360946,18 +361218,18 @@ null "s390x", "x86_64" ], -"id": 10153, +"id": 10157, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-grc", +"name": "hyphen-ia", "repository": "rhel8-AppStream" } ], -"set_id": 14100 +"set_id": 14102 }, "initial_release": { "major_version": 8, @@ -360980,18 +361252,18 @@ null "s390x", "x86_64" ], -"id": 10154, +"id": 10158, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-grc", +"name": "hyphen-ia", "repository": "rhel8-AppStream" } ], -"set_id": 19084 +"set_id": 19086 }, "initial_release": { "major_version": 8, @@ -361014,18 +361286,18 @@ null "s390x", "x86_64" ], -"id": 10155, +"id": 10159, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-hsb", +"name": "hyphen-is", "repository": "rhel8-AppStream" } ], -"set_id": 14101 +"set_id": 14103 }, "initial_release": { "major_version": 8, @@ -361048,18 +361320,18 @@ null "s390x", "x86_64" ], -"id": 10156, +"id": 10160, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-hsb", +"name": "hyphen-is", "repository": "rhel8-AppStream" } ], -"set_id": 19085 +"set_id": 19087 }, "initial_release": { "major_version": 8, @@ -361082,18 +361354,18 @@ null "s390x", "x86_64" ], -"id": 10157, +"id": 10161, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-ia", +"name": "hyphen-ku", "repository": "rhel8-AppStream" } ], -"set_id": 14102 +"set_id": 14104 }, "initial_release": { "major_version": 8, @@ -361116,18 +361388,18 @@ null "s390x", "x86_64" ], -"id": 10158, +"id": 10162, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-ia", +"name": "hyphen-ku", "repository": "rhel8-AppStream" } ], -"set_id": 19086 +"set_id": 19088 }, "initial_release": { "major_version": 8, @@ -361150,18 +361422,18 @@ null "s390x", "x86_64" ], -"id": 10159, +"id": 10163, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-is", +"name": "hyphen-mi", "repository": "rhel8-AppStream" } ], -"set_id": 14103 +"set_id": 14105 }, "initial_release": { "major_version": 8, @@ -361184,18 +361456,18 @@ null "s390x", "x86_64" ], -"id": 10160, +"id": 10164, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-is", +"name": "hyphen-mi", "repository": "rhel8-AppStream" } ], -"set_id": 19087 +"set_id": 19089 }, "initial_release": { "major_version": 8, @@ -361218,18 +361490,18 @@ null "s390x", "x86_64" ], -"id": 10161, +"id": 10165, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-ku", +"name": "hyphen-mn", "repository": "rhel8-AppStream" } ], -"set_id": 14104 +"set_id": 14106 }, "initial_release": { "major_version": 8, @@ -361252,18 +361524,18 @@ null "s390x", "x86_64" ], -"id": 10162, +"id": 10166, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-ku", +"name": "hyphen-mn", "repository": "rhel8-AppStream" } ], -"set_id": 19088 +"set_id": 19090 }, "initial_release": { "major_version": 8, @@ -361286,18 +361558,18 @@ null "s390x", "x86_64" ], -"id": 10163, +"id": 10167, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-mi", +"name": "hyphen-sa", "repository": "rhel8-AppStream" } ], -"set_id": 14105 +"set_id": 14107 }, "initial_release": { "major_version": 8, @@ -361320,18 +361592,18 @@ null "s390x", "x86_64" ], -"id": 10164, +"id": 10168, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-mi", +"name": "hyphen-sa", "repository": "rhel8-AppStream" } ], -"set_id": 19089 +"set_id": 19091 }, "initial_release": { "major_version": 8, @@ -361354,18 +361626,18 @@ null "s390x", "x86_64" ], -"id": 10165, +"id": 10169, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-mn", +"name": "hyphen-tk", "repository": "rhel8-AppStream" } ], -"set_id": 14106 +"set_id": 14108 }, "initial_release": { "major_version": 8, @@ -361388,18 +361660,18 @@ null "s390x", "x86_64" ], -"id": 10166, +"id": 10170, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-mn", +"name": "hyphen-tk", "repository": "rhel8-AppStream" } ], -"set_id": 19090 +"set_id": 19092 }, "initial_release": { "major_version": 8, @@ -361422,18 +361694,18 @@ null "s390x", "x86_64" ], -"id": 10167, +"id": 10171, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-sa", +"name": "ibus-sayura", "repository": "rhel8-AppStream" } ], -"set_id": 14107 +"set_id": 14109 }, "initial_release": { "major_version": 8, @@ -361456,18 +361728,18 @@ null "s390x", "x86_64" ], -"id": 10168, +"id": 10172, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-sa", +"name": "ibus-sayura", "repository": "rhel8-AppStream" } ], -"set_id": 19091 +"set_id": 19093 }, "initial_release": { "major_version": 8, @@ -361490,18 +361762,18 @@ null "s390x", "x86_64" ], -"id": 10169, +"id": 10173, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-tk", +"name": "kurdit-unikurd-web-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14108 +"set_id": 14110 }, "initial_release": { "major_version": 8, @@ -361524,18 +361796,18 @@ null "s390x", "x86_64" ], -"id": 10170, +"id": 10174, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "hyphen-tk", +"name": "kurdit-unikurd-web-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19092 +"set_id": 19094 }, "initial_release": { "major_version": 8, @@ -361558,18 +361830,18 @@ null "s390x", "x86_64" ], -"id": 10171, +"id": 10175, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "ibus-sayura", +"name": "kyotocabinet-libs", "repository": "rhel8-AppStream" } ], -"set_id": 14109 +"set_id": 14111 }, "initial_release": { "major_version": 8, @@ -361592,18 +361864,18 @@ null "s390x", "x86_64" ], -"id": 10172, +"id": 10176, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "ibus-sayura", +"name": "kyotocabinet-libs", "repository": "rhel8-AppStream" } ], -"set_id": 19093 +"set_id": 19095 }, "initial_release": { "major_version": 8, @@ -361626,18 +361898,18 @@ null "s390x", "x86_64" ], -"id": 10173, +"id": 10177, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "kurdit-unikurd-web-fonts", +"name": "libeasyfc", "repository": "rhel8-AppStream" } ], -"set_id": 14110 +"set_id": 14112 }, "initial_release": { "major_version": 8, @@ -361660,18 +361932,18 @@ null "s390x", "x86_64" ], -"id": 10174, +"id": 10178, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "kurdit-unikurd-web-fonts", +"name": "libeasyfc", "repository": "rhel8-AppStream" } ], -"set_id": 19094 +"set_id": 19096 }, "initial_release": { "major_version": 8, @@ -361694,18 +361966,18 @@ null "s390x", "x86_64" ], -"id": 10175, +"id": 10179, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "kyotocabinet-libs", +"name": "libeasyfc-gobject", "repository": "rhel8-AppStream" } ], -"set_id": 14111 +"set_id": 14113 }, "initial_release": { "major_version": 8, @@ -361728,18 +362000,18 @@ null "s390x", "x86_64" ], -"id": 10176, +"id": 10180, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "kyotocabinet-libs", +"name": "libeasyfc-gobject", "repository": "rhel8-AppStream" } ], -"set_id": 19095 +"set_id": 19097 }, "initial_release": { "major_version": 8, @@ -361762,18 +362034,18 @@ null "s390x", "x86_64" ], -"id": 10177, +"id": 10181, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libeasyfc", +"name": "libkkc", "repository": "rhel8-AppStream" } ], -"set_id": 14112 +"set_id": 14114 }, "initial_release": { "major_version": 8, @@ -361796,18 +362068,18 @@ null "s390x", "x86_64" ], -"id": 10178, +"id": 10182, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libeasyfc", +"name": "libkkc", "repository": "rhel8-AppStream" } ], -"set_id": 19096 +"set_id": 19098 }, "initial_release": { "major_version": 8, @@ -361830,18 +362102,18 @@ null "s390x", "x86_64" ], -"id": 10179, +"id": 10183, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libeasyfc-gobject", +"name": "libkkc-common", "repository": "rhel8-AppStream" } ], -"set_id": 14113 +"set_id": 14115 }, "initial_release": { "major_version": 8, @@ -361864,18 +362136,18 @@ null "s390x", "x86_64" ], -"id": 10180, +"id": 10184, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libeasyfc-gobject", +"name": "libkkc-common", "repository": "rhel8-AppStream" } ], -"set_id": 19097 +"set_id": 19099 }, "initial_release": { "major_version": 8, @@ -361898,18 +362170,18 @@ null "s390x", "x86_64" ], -"id": 10181, +"id": 10185, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libkkc", +"name": "libkkc-data", "repository": "rhel8-AppStream" } ], -"set_id": 14114 +"set_id": 14116 }, "initial_release": { "major_version": 8, @@ -361932,18 +362204,18 @@ null "s390x", "x86_64" ], -"id": 10182, +"id": 10186, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libkkc", +"name": "libkkc-data", "repository": "rhel8-AppStream" } ], -"set_id": 19098 +"set_id": 19100 }, "initial_release": { "major_version": 8, @@ -361966,18 +362238,18 @@ null "s390x", "x86_64" ], -"id": 10183, +"id": 10187, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libkkc-common", +"name": "libmalaga", "repository": "rhel8-AppStream" } ], -"set_id": 14115 +"set_id": 14117 }, "initial_release": { "major_version": 8, @@ -362000,18 +362272,18 @@ null "s390x", "x86_64" ], -"id": 10184, +"id": 10188, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libkkc-common", +"name": "libmalaga", "repository": "rhel8-AppStream" } ], -"set_id": 19099 +"set_id": 19101 }, "initial_release": { "major_version": 8, @@ -362034,18 +362306,18 @@ null "s390x", "x86_64" ], -"id": 10185, +"id": 10189, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libkkc-data", +"name": "lohit-malayalam-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14116 +"set_id": 14118 }, "initial_release": { "major_version": 8, @@ -362068,18 +362340,18 @@ null "s390x", "x86_64" ], -"id": 10186, +"id": 10190, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libkkc-data", +"name": "lohit-malayalam-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19100 +"set_id": 19102 }, "initial_release": { "major_version": 8, @@ -362102,18 +362374,18 @@ null "s390x", "x86_64" ], -"id": 10187, +"id": 10191, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libmalaga", +"name": "lohit-nepali-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 14117 +"set_id": 14119 }, "initial_release": { "major_version": 8, @@ -362136,18 +362408,18 @@ null "s390x", "x86_64" ], -"id": 10188, +"id": 10192, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "libmalaga", +"name": "lohit-nepali-fonts", "repository": "rhel8-AppStream" } ], -"set_id": 19101 +"set_id": 19103 }, "initial_release": { "major_version": 8, @@ -362170,18 +362442,18 @@ null "s390x", "x86_64" ], -"id": 10189, +"id": 10193, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "lohit-malayalam-fonts", +"name": "malaga", "repository": "rhel8-AppStream" } ], -"set_id": 14118 +"set_id": 14120 }, "initial_release": { "major_version": 8, @@ -362204,18 +362476,18 @@ null "s390x", "x86_64" ], -"id": 10190, +"id": 10194, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "lohit-malayalam-fonts", +"name": "malaga", "repository": "rhel8-AppStream" } ], -"set_id": 19102 +"set_id": 19104 }, "initial_release": { "major_version": 8, @@ -362238,18 +362510,18 @@ null "s390x", "x86_64" ], -"id": 10191, +"id": 10195, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "lohit-nepali-fonts", +"name": "malaga-suomi-voikko", "repository": "rhel8-AppStream" } ], -"set_id": 14119 +"set_id": 14121 }, "initial_release": { "major_version": 8, @@ -362272,18 +362544,18 @@ null "s390x", "x86_64" ], -"id": 10192, +"id": 10196, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "lohit-nepali-fonts", +"name": "malaga-suomi-voikko", "repository": "rhel8-AppStream" } ], -"set_id": 19103 +"set_id": 19105 }, "initial_release": { "major_version": 8, @@ -362306,18 +362578,18 @@ null "s390x", "x86_64" ], -"id": 10193, +"id": 10197, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "malaga", +"name": "marisa", "repository": "rhel8-AppStream" } ], -"set_id": 14120 +"set_id": 14122 }, "initial_release": { "major_version": 8, @@ -362340,18 +362612,18 @@ null "s390x", "x86_64" ], -"id": 10194, +"id": 10198, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "malaga", +"name": "marisa", "repository": "rhel8-AppStream" } ], -"set_id": 19104 +"set_id": 19106 }, "initial_release": { "major_version": 8, @@ -362374,18 +362646,18 @@ null "s390x", "x86_64" ], -"id": 10195, +"id": 10199, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "malaga-suomi-voikko", +"name": "mythes-mi", "repository": "rhel8-AppStream" } ], -"set_id": 14121 +"set_id": 14123 }, "initial_release": { "major_version": 8, @@ -362408,18 +362680,18 @@ null "s390x", "x86_64" ], -"id": 10196, +"id": 10200, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "malaga-suomi-voikko", +"name": "mythes-mi", "repository": "rhel8-AppStream" } ], -"set_id": 19105 +"set_id": 19107 }, "initial_release": { "major_version": 8, @@ -362442,18 +362714,18 @@ null "s390x", "x86_64" ], -"id": 10197, +"id": 10201, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "marisa", +"name": "mythes-ne", "repository": "rhel8-AppStream" } ], -"set_id": 14122 +"set_id": 14124 }, "initial_release": { "major_version": 8, @@ -362476,154 +362748,18 @@ null "s390x", "x86_64" ], -"id": 10198, +"id": 10202, "in_packageset": { "package": [ { "modulestreams": [ null ], -"name": "marisa", +"name": "mythes-ne", "repository": "rhel8-AppStream" } ], -"set_id": 19106 -}, -"initial_release": { -"major_version": 8, -"minor_version": 4, -"os_name": "RHEL" -}, -"modulestream_maps": [], -"out_packageset": null, -"release": { -"major_version": 8, -"minor_version": 5, -"os_name": "RHEL" -} -}, -{ -"action": 1, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 10199, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "mythes-mi", -"repository": "rhel8-AppStream" -} -], -"set_id": 14123 -}, -"initial_release": { -"major_version": 8, -"minor_version": 5, -"os_name": "RHEL" -}, -"modulestream_maps": [], -"out_packageset": null, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 2, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 10200, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "mythes-mi", -"repository": "rhel8-AppStream" -} -], -"set_id": 19107 -}, -"initial_release": { -"major_version": 8, -"minor_version": 4, -"os_name": "RHEL" -}, -"modulestream_maps": [], -"out_packageset": null, -"release": { -"major_version": 8, -"minor_version": 5, -"os_name": "RHEL" -} -}, -{ -"action": 1, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 10201, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "mythes-ne", -"repository": "rhel8-AppStream" -} -], -"set_id": 14124 -}, -"initial_release": { -"major_version": 8, -"minor_version": 5, -"os_name": "RHEL" -}, -"modulestream_maps": [], -"out_packageset": null, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 2, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 10202, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "mythes-ne", -"repository": "rhel8-AppStream" -} -], -"set_id": 19108 +"set_id": 19108 }, "initial_release": { "major_version": 8, @@ -364505,6 +364641,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php", @@ -364525,6 +364673,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -364534,7 +364703,7 @@ null null ], "name": "php", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14230 @@ -364561,6 +364730,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-bcmath", @@ -364581,6 +364762,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -364590,7 +364792,7 @@ null null ], "name": "php-bcmath", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14232 @@ -364617,6 +364819,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-cli", @@ -364637,6 +364851,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -364646,7 +364881,7 @@ null null ], "name": "php-cli", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14234 @@ -364673,6 +364908,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-common", @@ -364693,6 +364940,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -364702,7 +364970,7 @@ null null ], "name": "php-common", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14236 @@ -364729,6 +364997,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-dba", @@ -364749,6 +365029,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -364758,7 +365059,7 @@ null null ], "name": "php-dba", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14238 @@ -364785,6 +365086,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-dbg", @@ -364805,6 +365118,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -364814,7 +365148,7 @@ null null ], "name": "php-dbg", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14240 @@ -364841,6 +365175,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-devel", @@ -364861,6 +365207,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -364870,7 +365237,7 @@ null null ], "name": "php-devel", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14242 @@ -364897,6 +365264,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-embedded", @@ -364917,6 +365296,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -364926,7 +365326,7 @@ null null ], "name": "php-embedded", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14244 @@ -364953,6 +365353,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-enchant", @@ -364973,6 +365385,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -364982,7 +365415,7 @@ null null ], "name": "php-enchant", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14246 @@ -365009,6 +365442,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-fpm", @@ -365029,6 +365474,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365038,7 +365504,7 @@ null null ], "name": "php-fpm", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14248 @@ -365065,6 +365531,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-gd", @@ -365085,6 +365563,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365094,7 +365593,7 @@ null null ], "name": "php-gd", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14250 @@ -365121,6 +365620,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-gmp", @@ -365141,6 +365652,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365150,7 +365682,7 @@ null null ], "name": "php-gmp", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14252 @@ -365177,6 +365709,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-intl", @@ -365197,6 +365741,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365206,7 +365771,7 @@ null null ], "name": "php-intl", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14254 @@ -365218,7 +365783,7 @@ null } }, { -"action": 6, +"action": 1, "architectures": [ "aarch64", "ppc64le", @@ -365233,6 +365798,14 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" } ], "name": "php-json", @@ -365246,27 +365819,8 @@ null "minor_version": 6, "os_name": "RHEL" }, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "php", -"stream": "7.2" -}, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "php-json", -"repository": "rhel9-BaseOS" -} -], -"set_id": 14256 -}, +"modulestream_maps": [], +"out_packageset": null, "release": { "major_version": 9, "minor_version": 0, @@ -365289,6 +365843,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-ldap", @@ -365309,6 +365875,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365318,7 +365905,7 @@ null null ], "name": "php-ldap", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14258 @@ -365345,6 +365932,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-mbstring", @@ -365365,6 +365964,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365374,7 +365994,7 @@ null null ], "name": "php-mbstring", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14260 @@ -365401,6 +366021,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-mysqlnd", @@ -365421,6 +366053,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365430,7 +366083,7 @@ null null ], "name": "php-mysqlnd", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14262 @@ -365457,6 +366110,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-odbc", @@ -365477,6 +366142,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365486,7 +366172,7 @@ null null ], "name": "php-odbc", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14264 @@ -365513,6 +366199,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-opcache", @@ -365533,6 +366231,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365542,7 +366261,7 @@ null null ], "name": "php-opcache", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14266 @@ -365569,6 +366288,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-pdo", @@ -365589,6 +366320,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365598,7 +366350,7 @@ null null ], "name": "php-pdo", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14268 @@ -365687,7 +366439,7 @@ null null ], "name": "php-pear", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14270 @@ -365714,6 +366466,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-pecl-apcu", @@ -365734,6 +366498,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365770,6 +366555,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-pecl-apcu-devel", @@ -365790,6 +366587,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365799,7 +366617,7 @@ null null ], "name": "php-pecl-apcu-devel", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14274 @@ -365826,6 +366644,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-pecl-zip", @@ -365846,6 +366676,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365855,7 +366706,7 @@ null null ], "name": "php-pecl-zip", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14276 @@ -365882,6 +366733,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-pgsql", @@ -365902,6 +366765,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365911,7 +366795,7 @@ null null ], "name": "php-pgsql", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14278 @@ -365938,6 +366822,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-process", @@ -365958,6 +366854,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -365967,7 +366884,7 @@ null null ], "name": "php-process", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14280 @@ -365994,6 +366911,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-snmp", @@ -366014,6 +366943,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -366023,7 +366973,7 @@ null null ], "name": "php-snmp", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14282 @@ -366050,6 +367000,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-soap", @@ -366070,6 +367032,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -366079,7 +367062,7 @@ null null ], "name": "php-soap", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14284 @@ -366106,6 +367089,18 @@ null { "name": "php", "stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" } ], "name": "php-xml", @@ -366126,6 +367121,27 @@ null "stream": "7.2" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.3" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null } ], "out_packageset": { @@ -366135,7 +367151,7 @@ null null ], "name": "php-xml", -"repository": "rhel9-BaseOS" +"repository": "rhel9-AppStream" } ], "set_id": 14286 @@ -373452,9 +374468,6 @@ null { "action": 6, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 10499, @@ -373750,9 +374763,6 @@ null { "action": 6, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 10505, @@ -373806,9 +374816,6 @@ null { "action": 6, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 10506, @@ -373936,9 +374943,6 @@ null { "action": 6, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 10509, @@ -374048,9 +375052,6 @@ null { "action": 6, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 10511, @@ -374138,9 +375139,6 @@ null { "action": 6, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 10513, @@ -374250,9 +375248,6 @@ null { "action": 6, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 10515, @@ -374473,9 +375468,6 @@ null { "action": 6, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 10520, @@ -381535,9 +382527,6 @@ null { "action": 1, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 10697, @@ -381572,9 +382561,6 @@ null { "action": 2, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 10698, @@ -399589,10 +400575,6 @@ null "modulestreams": [ { "name": "maven", -"stream": "3.5" -}, -{ -"name": "maven", "stream": "3.6" } ], @@ -399614,13 +400596,297 @@ null "stream": "3.6" }, "out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "maven-resolver", +"repository": "rhel9-AppStream" +} +], +"set_id": 15499 +}, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 11177, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "javapackages-tools", +"stream": "201801" +} +], +"name": "ant", +"repository": "rhel8-CRB" +} +], +"set_id": 15502 +}, +"initial_release": { +"major_version": 8, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +}, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "ant", +"repository": "rhel9-AppStream" +} +], +"set_id": 15503 +}, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 11178, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "javapackages-tools", +"stream": "201801" +} +], +"name": "ant-lib", +"repository": "rhel8-CRB" +} +], +"set_id": 15506 +}, +"initial_release": { +"major_version": 8, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +}, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "ant-lib", +"repository": "rhel9-AppStream" +} +], +"set_id": 15507 +}, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 11179, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "javapackages-tools", +"stream": "201801" +} +], +"name": "javapackages-filesystem", +"repository": "rhel8-CRB" +} +], +"set_id": 15510 +}, +"initial_release": { +"major_version": 8, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +}, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "javapackages-filesystem", +"repository": "rhel9-AppStream" +} +], +"set_id": 15511 +}, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 11180, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "javapackages-tools", +"stream": "201801" +} +], +"name": "javapackages-tools", +"repository": "rhel8-CRB" +} +], +"set_id": 15514 +}, +"initial_release": { +"major_version": 8, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "javapackages-tools", +"stream": "201801" +}, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "javapackages-tools", +"repository": "rhel9-AppStream" +} +], +"set_id": 15515 +}, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 11181, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "maven", +"stream": "3.5" }, { +"name": "maven", +"stream": "3.6" +} +], +"name": "apache-commons-io", +"repository": "rhel8-AppStream" +} +], +"set_id": 15518 +}, +"initial_release": { +"major_version": 8, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ "in_modulestream": { "name": "maven", "stream": "3.5" }, "out_modulestream": null +}, +{ +"in_modulestream": { +"name": "maven", +"stream": "3.6" +}, +"out_modulestream": null } ], "out_packageset": { @@ -399629,11 +400895,11 @@ null "modulestreams": [ null ], -"name": "maven-resolver", +"name": "apache-commons-io", "repository": "rhel9-AppStream" } ], -"set_id": 15499 +"set_id": 15519 }, "release": { "major_version": 9, @@ -399649,7 +400915,7 @@ null "s390x", "x86_64" ], -"id": 11177, +"id": 11182, "in_packageset": { "package": [ { @@ -399659,11 +400925,11 @@ null "stream": "201801" } ], -"name": "ant", +"name": "apache-commons-logging", "repository": "rhel8-CRB" } ], -"set_id": 15502 +"set_id": 15522 }, "initial_release": { "major_version": 8, @@ -399685,11 +400951,11 @@ null "modulestreams": [ null ], -"name": "ant", +"name": "apache-commons-logging", "repository": "rhel9-AppStream" } ], -"set_id": 15503 +"set_id": 15523 }, "release": { "major_version": 9, @@ -399705,7 +400971,7 @@ null "s390x", "x86_64" ], -"id": 11178, +"id": 11183, "in_packageset": { "package": [ { @@ -399715,11 +400981,11 @@ null "stream": "201801" } ], -"name": "ant-lib", +"name": "apache-commons-net", "repository": "rhel8-CRB" } ], -"set_id": 15506 +"set_id": 15526 }, "initial_release": { "major_version": 8, @@ -399741,11 +401007,11 @@ null "modulestreams": [ null ], -"name": "ant-lib", +"name": "apache-commons-net", "repository": "rhel9-AppStream" } ], -"set_id": 15507 +"set_id": 15527 }, "release": { "major_version": 9, @@ -399761,21 +401027,25 @@ null "s390x", "x86_64" ], -"id": 11179, +"id": 11184, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "javapackages-tools", -"stream": "201801" +"name": "maven", +"stream": "3.5" +}, +{ +"name": "maven", +"stream": "3.6" } ], -"name": "javapackages-filesystem", -"repository": "rhel8-CRB" +"name": "atinject", +"repository": "rhel8-AppStream" } ], -"set_id": 15510 +"set_id": 15528 }, "initial_release": { "major_version": 8, @@ -399785,8 +401055,15 @@ null "modulestream_maps": [ { "in_modulestream": { -"name": "javapackages-tools", -"stream": "201801" +"name": "maven", +"stream": "3.5" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "maven", +"stream": "3.6" }, "out_modulestream": null } @@ -399797,11 +401074,11 @@ null "modulestreams": [ null ], -"name": "javapackages-filesystem", +"name": "atinject", "repository": "rhel9-AppStream" } ], -"set_id": 15511 +"set_id": 15529 }, "release": { "major_version": 9, @@ -399817,21 +401094,25 @@ null "s390x", "x86_64" ], -"id": 11180, +"id": 11185, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "javapackages-tools", -"stream": "201801" +"name": "maven", +"stream": "3.5" +}, +{ +"name": "maven", +"stream": "3.6" } ], -"name": "javapackages-tools", -"repository": "rhel8-CRB" +"name": "cdi-api", +"repository": "rhel8-AppStream" } ], -"set_id": 15514 +"set_id": 15532 }, "initial_release": { "major_version": 8, @@ -399841,8 +401122,15 @@ null "modulestream_maps": [ { "in_modulestream": { -"name": "javapackages-tools", -"stream": "201801" +"name": "maven", +"stream": "3.5" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "maven", +"stream": "3.6" }, "out_modulestream": null } @@ -399853,11 +401141,11 @@ null "modulestreams": [ null ], -"name": "javapackages-tools", +"name": "cdi-api", "repository": "rhel9-AppStream" } ], -"set_id": 15515 +"set_id": 15533 }, "release": { "major_version": 9, @@ -399873,7 +401161,7 @@ null "s390x", "x86_64" ], -"id": 11181, +"id": 11186, "in_packageset": { "package": [ { @@ -399887,11 +401175,11 @@ null "stream": "3.6" } ], -"name": "apache-commons-io", +"name": "google-guice", "repository": "rhel8-AppStream" } ], -"set_id": 15518 +"set_id": 15536 }, "initial_release": { "major_version": 8, @@ -399920,11 +401208,11 @@ null "modulestreams": [ null ], -"name": "apache-commons-io", +"name": "google-guice", "repository": "rhel9-AppStream" } ], -"set_id": 15519 +"set_id": 15537 }, "release": { "major_version": 9, @@ -399935,26 +401223,23 @@ null { "action": 6, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], -"id": 11182, +"id": 11187, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "javapackages-tools", -"stream": "201801" +"name": "eclipse", +"stream": "rhel8" } ], -"name": "apache-commons-logging", -"repository": "rhel8-CRB" +"name": "hamcrest", +"repository": "rhel8-AppStream" } ], -"set_id": 15522 +"set_id": 15542 }, "initial_release": { "major_version": 8, @@ -399964,8 +401249,8 @@ null "modulestream_maps": [ { "in_modulestream": { -"name": "javapackages-tools", -"stream": "201801" +"name": "eclipse", +"stream": "rhel8" }, "out_modulestream": null } @@ -399976,11 +401261,11 @@ null "modulestreams": [ null ], -"name": "apache-commons-logging", +"name": "hamcrest", "repository": "rhel9-AppStream" } ], -"set_id": 15523 +"set_id": 15543 }, "release": { "major_version": 9, @@ -399996,21 +401281,25 @@ null "s390x", "x86_64" ], -"id": 11183, +"id": 11188, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "javapackages-tools", -"stream": "201801" +"name": "maven", +"stream": "3.5" +}, +{ +"name": "maven", +"stream": "3.6" } ], -"name": "apache-commons-net", -"repository": "rhel8-CRB" +"name": "httpcomponents-core", +"repository": "rhel8-AppStream" } ], -"set_id": 15526 +"set_id": 15544 }, "initial_release": { "major_version": 8, @@ -400020,8 +401309,15 @@ null "modulestream_maps": [ { "in_modulestream": { -"name": "javapackages-tools", -"stream": "201801" +"name": "maven", +"stream": "3.5" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "maven", +"stream": "3.6" }, "out_modulestream": null } @@ -400032,11 +401328,11 @@ null "modulestreams": [ null ], -"name": "apache-commons-net", +"name": "httpcomponents-core", "repository": "rhel9-AppStream" } ], -"set_id": 15527 +"set_id": 15545 }, "release": { "major_version": 9, @@ -400052,7 +401348,7 @@ null "s390x", "x86_64" ], -"id": 11184, +"id": 11189, "in_packageset": { "package": [ { @@ -400064,13 +401360,17 @@ null { "name": "maven", "stream": "3.6" +}, +{ +"name": "scala", +"stream": "2.10" } ], -"name": "atinject", +"name": "jansi", "repository": "rhel8-AppStream" } ], -"set_id": 15528 +"set_id": 15550 }, "initial_release": { "major_version": 8, @@ -400080,6 +401380,13 @@ null "modulestream_maps": [ { "in_modulestream": { +"name": "scala", +"stream": "2.10" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { "name": "maven", "stream": "3.5" }, @@ -400099,11 +401406,11 @@ null "modulestreams": [ null ], -"name": "atinject", +"name": "jansi", "repository": "rhel9-AppStream" } ], -"set_id": 15529 +"set_id": 15551 }, "release": { "major_version": 9, @@ -400119,7 +401426,7 @@ null "s390x", "x86_64" ], -"id": 11185, +"id": 11190, "in_packageset": { "package": [ { @@ -400133,11 +401440,11 @@ null "stream": "3.6" } ], -"name": "cdi-api", +"name": "jsoup", "repository": "rhel8-AppStream" } ], -"set_id": 15532 +"set_id": 15554 }, "initial_release": { "major_version": 8, @@ -400166,11 +401473,11 @@ null "modulestreams": [ null ], -"name": "cdi-api", +"name": "jsoup", "repository": "rhel9-AppStream" } ], -"set_id": 15533 +"set_id": 15555 }, "release": { "major_version": 9, @@ -400186,25 +401493,21 @@ null "s390x", "x86_64" ], -"id": 11186, +"id": 11191, "in_packageset": { "package": [ { "modulestreams": [ { "name": "maven", -"stream": "3.5" -}, -{ -"name": "maven", "stream": "3.6" } ], -"name": "google-guice", +"name": "jsr-305", "repository": "rhel8-AppStream" } ], -"set_id": 15536 +"set_id": 15558 }, "initial_release": { "major_version": 8, @@ -400215,14 +401518,60 @@ null { "in_modulestream": { "name": "maven", -"stream": "3.5" +"stream": "3.6" }, "out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "jsr-305", +"repository": "rhel9-AppStream" +} +], +"set_id": 15559 +}, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"x86_64" +], +"id": 11192, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "eclipse", +"stream": "rhel8" +} +], +"name": "junit", +"repository": "rhel8-AppStream" +} +], +"set_id": 15562 }, +"initial_release": { +"major_version": 8, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [ { "in_modulestream": { -"name": "maven", -"stream": "3.6" +"name": "eclipse", +"stream": "rhel8" }, "out_modulestream": null } @@ -400233,11 +401582,11 @@ null "modulestreams": [ null ], -"name": "google-guice", +"name": "junit", "repository": "rhel9-AppStream" } ], -"set_id": 15537 +"set_id": 15563 }, "release": { "major_version": 9, @@ -400253,21 +401602,25 @@ null "s390x", "x86_64" ], -"id": 11187, +"id": 11193, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "eclipse", -"stream": "rhel8" +"name": "maven", +"stream": "3.5" +}, +{ +"name": "maven", +"stream": "3.6" } ], -"name": "hamcrest", +"name": "maven-lib", "repository": "rhel8-AppStream" } ], -"set_id": 15542 +"set_id": 15566 }, "initial_release": { "major_version": 8, @@ -400277,8 +401630,15 @@ null "modulestream_maps": [ { "in_modulestream": { -"name": "eclipse", -"stream": "rhel8" +"name": "maven", +"stream": "3.5" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "maven", +"stream": "3.6" }, "out_modulestream": null } @@ -400289,11 +401649,11 @@ null "modulestreams": [ null ], -"name": "hamcrest", +"name": "maven-lib", "repository": "rhel9-AppStream" } ], -"set_id": 15543 +"set_id": 15567 }, "release": { "major_version": 9, @@ -400309,7 +401669,7 @@ null "s390x", "x86_64" ], -"id": 11188, +"id": 11194, "in_packageset": { "package": [ { @@ -400323,11 +401683,11 @@ null "stream": "3.6" } ], -"name": "httpcomponents-core", +"name": "maven", "repository": "rhel8-AppStream" } ], -"set_id": 15544 +"set_id": 15570 }, "initial_release": { "major_version": 8, @@ -400356,11 +401716,11 @@ null "modulestreams": [ null ], -"name": "httpcomponents-core", +"name": "maven", "repository": "rhel9-AppStream" } ], -"set_id": 15545 +"set_id": 15571 }, "release": { "major_version": 9, @@ -400376,7 +401736,7 @@ null "s390x", "x86_64" ], -"id": 11189, +"id": 11195, "in_packageset": { "package": [ { @@ -400388,17 +401748,13 @@ null { "name": "maven", "stream": "3.6" -}, -{ -"name": "scala", -"stream": "2.10" } ], -"name": "jansi", +"name": "maven-shared-utils", "repository": "rhel8-AppStream" } ], -"set_id": 15550 +"set_id": 15574 }, "initial_release": { "major_version": 8, @@ -400408,13 +401764,6 @@ null "modulestream_maps": [ { "in_modulestream": { -"name": "scala", -"stream": "2.10" -}, -"out_modulestream": null -}, -{ -"in_modulestream": { "name": "maven", "stream": "3.5" }, @@ -400434,11 +401783,11 @@ null "modulestreams": [ null ], -"name": "jansi", +"name": "maven-shared-utils", "repository": "rhel9-AppStream" } ], -"set_id": 15551 +"set_id": 15575 }, "release": { "major_version": 9, @@ -400447,32 +401796,28 @@ null } }, { -"action": 6, +"action": 7, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 11190, +"id": 11196, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "maven", -"stream": "3.5" -}, -{ -"name": "maven", -"stream": "3.6" +"name": "ruby", +"stream": "2.5" } ], -"name": "jsoup", +"name": "ruby-irb", "repository": "rhel8-AppStream" } ], -"set_id": 15554 +"set_id": 15576 }, "initial_release": { "major_version": 8, @@ -400482,15 +401827,8 @@ null "modulestream_maps": [ { "in_modulestream": { -"name": "maven", -"stream": "3.5" -}, -"out_modulestream": null -}, -{ -"in_modulestream": { -"name": "maven", -"stream": "3.6" +"name": "ruby", +"stream": "2.5" }, "out_modulestream": null } @@ -400501,11 +401839,11 @@ null "modulestreams": [ null ], -"name": "jsoup", +"name": "rubygem-irb", "repository": "rhel9-AppStream" } ], -"set_id": 15555 +"set_id": 15577 }, "release": { "major_version": 9, @@ -400521,7 +401859,7 @@ null "s390x", "x86_64" ], -"id": 11191, +"id": 11197, "in_packageset": { "package": [ { @@ -400531,11 +401869,11 @@ null "stream": "3.6" } ], -"name": "jsr-305", +"name": "maven-wagon", "repository": "rhel8-AppStream" } ], -"set_id": 15558 +"set_id": 15580 }, "initial_release": { "major_version": 8, @@ -400557,11 +401895,11 @@ null "modulestreams": [ null ], -"name": "jsr-305", +"name": "maven-wagon", "repository": "rhel9-AppStream" } ], -"set_id": 15559 +"set_id": 15581 }, "release": { "major_version": 9, @@ -400570,88 +401908,38 @@ null } }, { -"action": 6, +"action": 5, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 11192, +"id": 11198, "in_packageset": { "package": [ { "modulestreams": [ { -"name": "eclipse", -"stream": "rhel8" +"name": "maven", +"stream": "3.6" } ], -"name": "junit", +"name": "guava", "repository": "rhel8-AppStream" -} -], -"set_id": 15562 }, -"initial_release": { -"major_version": 8, -"minor_version": 6, -"os_name": "RHEL" -}, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "eclipse", -"stream": "rhel8" -}, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "junit", -"repository": "rhel9-AppStream" -} -], -"set_id": 15563 -}, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 6, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 11193, -"in_packageset": { -"package": [ { "modulestreams": [ { "name": "maven", "stream": "3.5" -}, -{ -"name": "maven", -"stream": "3.6" } ], -"name": "maven-lib", +"name": "guava20", "repository": "rhel8-AppStream" } ], -"set_id": 15566 +"set_id": 15582 }, "initial_release": { "major_version": 8, @@ -400680,11 +401968,11 @@ null "modulestreams": [ null ], -"name": "maven-lib", +"name": "guava", "repository": "rhel9-AppStream" } ], -"set_id": 15567 +"set_id": 15583 }, "release": { "major_version": 9, @@ -400700,7 +401988,7 @@ null "s390x", "x86_64" ], -"id": 11194, +"id": 11199, "in_packageset": { "package": [ { @@ -400714,11 +402002,11 @@ null "stream": "3.6" } ], -"name": "maven", +"name": "plexus-cipher", "repository": "rhel8-AppStream" } ], -"set_id": 15570 +"set_id": 15586 }, "initial_release": { "major_version": 8, @@ -400747,11 +402035,11 @@ null "modulestreams": [ null ], -"name": "maven", +"name": "plexus-cipher", "repository": "rhel9-AppStream" } ], -"set_id": 15571 +"set_id": 15587 }, "release": { "major_version": 9, @@ -400767,7 +402055,7 @@ null "s390x", "x86_64" ], -"id": 11195, +"id": 11200, "in_packageset": { "package": [ { @@ -400781,11 +402069,11 @@ null "stream": "3.6" } ], -"name": "maven-shared-utils", +"name": "plexus-classworlds", "repository": "rhel8-AppStream" } ], -"set_id": 15574 +"set_id": 15590 }, "initial_release": { "major_version": 8, @@ -400814,67 +402102,11 @@ null "modulestreams": [ null ], -"name": "maven-shared-utils", -"repository": "rhel9-AppStream" -} -], -"set_id": 15575 -}, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 7, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 11196, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -{ -"name": "ruby", -"stream": "2.5" -} -], -"name": "ruby-irb", -"repository": "rhel8-AppStream" -} -], -"set_id": 15576 -}, -"initial_release": { -"major_version": 8, -"minor_version": 6, -"os_name": "RHEL" -}, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "ruby", -"stream": "2.5" -}, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "rubygem-irb", +"name": "plexus-classworlds", "repository": "rhel9-AppStream" } ], -"set_id": 15577 +"set_id": 15591 }, "release": { "major_version": 9, @@ -400890,7 +402122,7 @@ null "s390x", "x86_64" ], -"id": 11197, +"id": 11201, "in_packageset": { "package": [ { @@ -400904,11 +402136,11 @@ null "stream": "3.6" } ], -"name": "maven-wagon", +"name": "plexus-containers-component-annotations", "repository": "rhel8-AppStream" } ], -"set_id": 15580 +"set_id": 15594 }, "initial_release": { "major_version": 8, @@ -400919,14 +402151,14 @@ null { "in_modulestream": { "name": "maven", -"stream": "3.6" +"stream": "3.5" }, "out_modulestream": null }, { "in_modulestream": { "name": "maven", -"stream": "3.5" +"stream": "3.6" }, "out_modulestream": null } @@ -400937,11 +402169,11 @@ null "modulestreams": [ null ], -"name": "maven-wagon", +"name": "plexus-containers-component-annotations", "repository": "rhel9-AppStream" } ], -"set_id": 15581 +"set_id": 15595 }, "release": { "major_version": 9, @@ -400950,38 +402182,32 @@ null } }, { -"action": 5, +"action": 6, "architectures": [ "aarch64", "ppc64le", "s390x", "x86_64" ], -"id": 11198, +"id": 11202, "in_packageset": { "package": [ { "modulestreams": [ { "name": "maven", -"stream": "3.6" -} -], -"name": "guava", -"repository": "rhel8-AppStream" +"stream": "3.5" }, { -"modulestreams": [ -{ "name": "maven", -"stream": "3.5" +"stream": "3.6" } ], -"name": "guava20", +"name": "plexus-containers", "repository": "rhel8-AppStream" } ], -"set_id": 15582 +"set_id": 15598 }, "initial_release": { "major_version": 8, @@ -401010,11 +402236,11 @@ null "modulestreams": [ null ], -"name": "guava", +"name": "plexus-containers", "repository": "rhel9-AppStream" } ], -"set_id": 15583 +"set_id": 15599 }, "release": { "major_version": 9, @@ -401030,7 +402256,7 @@ null "s390x", "x86_64" ], -"id": 11199, +"id": 11203, "in_packageset": { "package": [ { @@ -401044,11 +402270,11 @@ null "stream": "3.6" } ], -"name": "plexus-cipher", +"name": "plexus-interpolation", "repository": "rhel8-AppStream" } ], -"set_id": 15586 +"set_id": 15602 }, "initial_release": { "major_version": 8, @@ -401077,11 +402303,11 @@ null "modulestreams": [ null ], -"name": "plexus-cipher", +"name": "plexus-interpolation", "repository": "rhel9-AppStream" } ], -"set_id": 15587 +"set_id": 15603 }, "release": { "major_version": 9, @@ -401097,7 +402323,7 @@ null "s390x", "x86_64" ], -"id": 11200, +"id": 11204, "in_packageset": { "package": [ { @@ -401111,279 +402337,11 @@ null "stream": "3.6" } ], -"name": "plexus-classworlds", +"name": "plexus-sec-dispatcher", "repository": "rhel8-AppStream" } ], -"set_id": 15590 -}, -"initial_release": { -"major_version": 8, -"minor_version": 6, -"os_name": "RHEL" -}, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "maven", -"stream": "3.5" -}, -"out_modulestream": null -}, -{ -"in_modulestream": { -"name": "maven", -"stream": "3.6" -}, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "plexus-classworlds", -"repository": "rhel9-AppStream" -} -], -"set_id": 15591 -}, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 6, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 11201, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -{ -"name": "maven", -"stream": "3.5" -}, -{ -"name": "maven", -"stream": "3.6" -} -], -"name": "plexus-containers-component-annotations", -"repository": "rhel8-AppStream" -} -], -"set_id": 15594 -}, -"initial_release": { -"major_version": 8, -"minor_version": 6, -"os_name": "RHEL" -}, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "maven", -"stream": "3.5" -}, -"out_modulestream": null -}, -{ -"in_modulestream": { -"name": "maven", -"stream": "3.6" -}, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "plexus-containers-component-annotations", -"repository": "rhel9-AppStream" -} -], -"set_id": 15595 -}, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 6, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 11202, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -{ -"name": "maven", -"stream": "3.5" -}, -{ -"name": "maven", -"stream": "3.6" -} -], -"name": "plexus-containers", -"repository": "rhel8-AppStream" -} -], -"set_id": 15598 -}, -"initial_release": { -"major_version": 8, -"minor_version": 6, -"os_name": "RHEL" -}, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "maven", -"stream": "3.5" -}, -"out_modulestream": null -}, -{ -"in_modulestream": { -"name": "maven", -"stream": "3.6" -}, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "plexus-containers", -"repository": "rhel9-AppStream" -} -], -"set_id": 15599 -}, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 6, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 11203, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -{ -"name": "maven", -"stream": "3.5" -}, -{ -"name": "maven", -"stream": "3.6" -} -], -"name": "plexus-interpolation", -"repository": "rhel8-AppStream" -} -], -"set_id": 15602 -}, -"initial_release": { -"major_version": 8, -"minor_version": 6, -"os_name": "RHEL" -}, -"modulestream_maps": [ -{ -"in_modulestream": { -"name": "maven", -"stream": "3.5" -}, -"out_modulestream": null -}, -{ -"in_modulestream": { -"name": "maven", -"stream": "3.6" -}, -"out_modulestream": null -} -], -"out_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "plexus-interpolation", -"repository": "rhel9-AppStream" -} -], -"set_id": 15603 -}, -"release": { -"major_version": 9, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 6, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], -"id": 11204, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -{ -"name": "maven", -"stream": "3.5" -}, -{ -"name": "maven", -"stream": "3.6" -} -], -"name": "plexus-sec-dispatcher", -"repository": "rhel8-AppStream" -} -], -"set_id": 15606 +"set_id": 15606 }, "initial_release": { "major_version": 8, @@ -401567,10 +402525,6 @@ null { "name": "maven", "stream": "3.6" -}, -{ -"name": "pki-deps", -"stream": "10.6" } ], "name": "jcl-over-slf4j", @@ -401598,13 +402552,6 @@ null "stream": "3.6" }, "out_modulestream": null -}, -{ -"in_modulestream": { -"name": "pki-deps", -"stream": "10.6" -}, -"out_modulestream": null } ], "out_packageset": { @@ -401639,14 +402586,6 @@ null { "modulestreams": [ { -"name": "maven", -"stream": "3.5" -}, -{ -"name": "maven", -"stream": "3.6" -}, -{ "name": "pki-deps", "stream": "10.6" } @@ -401669,20 +402608,6 @@ null "stream": "10.6" }, "out_modulestream": null -}, -{ -"in_modulestream": { -"name": "maven", -"stream": "3.5" -}, -"out_modulestream": null -}, -{ -"in_modulestream": { -"name": "maven", -"stream": "3.6" -}, -"out_modulestream": null } ], "out_packageset": { @@ -405018,9 +405943,6 @@ null { "action": 6, "architectures": [ -"aarch64", -"ppc64le", -"s390x", "x86_64" ], "id": 11259, @@ -405038,7 +405960,7 @@ null }, "initial_release": { "major_version": 8, -"minor_version": 6, +"minor_version": 10, "os_name": "RHEL" }, "modulestream_maps": [ @@ -511782,21 +512704,21 @@ null null ], "name": "rpm-sequoia", -"repository": "rhel10-BaseOS" +"repository": "rhel9-BaseOS" } ], "set_id": 19997 }, "initial_release": { "major_version": 9, -"minor_version": 5, +"minor_version": 6, "os_name": "RHEL" }, "modulestream_maps": [], "out_packageset": null, "release": { -"major_version": 10, -"minor_version": 0, +"major_version": 9, +"minor_version": 7, "os_name": "RHEL" } }, @@ -597343,40 +598265,6 @@ null "s390x", "x86_64" ], -"id": 16619, -"in_packageset": { -"package": [ -{ -"modulestreams": [ -null -], -"name": "ocaml-augeas", -"repository": "rhel9-CRB" -} -], -"set_id": 22803 -}, -"initial_release": { -"major_version": 9, -"minor_version": 5, -"os_name": "RHEL" -}, -"modulestream_maps": [], -"out_packageset": null, -"release": { -"major_version": 10, -"minor_version": 0, -"os_name": "RHEL" -} -}, -{ -"action": 1, -"architectures": [ -"aarch64", -"ppc64le", -"s390x", -"x86_64" -], "id": 16620, "in_packageset": { "package": [ @@ -602177,7 +603065,7 @@ null null ], "name": "amd-gpu-firmware", -"repository": "rhel10-BaseOS" +"repository": "rhel10-AppStream" }, { "modulestreams": [ @@ -602226,7 +603114,7 @@ null null ], "name": "intel-gpu-firmware", -"repository": "rhel10-BaseOS" +"repository": "rhel10-AppStream" }, { "modulestreams": [ @@ -602268,7 +603156,7 @@ null null ], "name": "nvidia-gpu-firmware", -"repository": "rhel10-BaseOS" +"repository": "rhel10-AppStream" }, { "modulestreams": [ @@ -621056,14 +621944,14 @@ null }, "initial_release": { "major_version": 9, -"minor_version": 5, +"minor_version": 4, "os_name": "RHEL" }, "modulestream_maps": [], "out_packageset": null, "release": { "major_version": 9, -"minor_version": 6, +"minor_version": 5, "os_name": "RHEL" } }, @@ -695612,6 +696500,3472 @@ null "minor_version": 0, "os_name": "RHEL" } +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19565, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "libgfortran-static", +"repository": "rhel8-CRB" +} +], +"set_id": 26171 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"ppc64le", +"x86_64" +], +"id": 19566, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "libquadmath-static", +"repository": "rhel8-CRB" +} +], +"set_id": 26172 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 1, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19567, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "libgfortran-static", +"repository": "rhel8-CRB" +} +], +"set_id": 26173 +}, +"initial_release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 1, +"architectures": [ +"ppc64le", +"x86_64" +], +"id": 19568, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "libquadmath-static", +"repository": "rhel8-CRB" +} +], +"set_id": 26174 +}, +"initial_release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19569, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "libgfortran-static", +"repository": "rhel9-CRB" +} +], +"set_id": 26175 +}, +"initial_release": { +"major_version": 9, +"minor_version": 4, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 5, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"ppc64le", +"x86_64" +], +"id": 19570, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "libquadmath-static", +"repository": "rhel9-CRB" +} +], +"set_id": 26176 +}, +"initial_release": { +"major_version": 9, +"minor_version": 4, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 5, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19571, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "gcc-toolset-15", +"repository": "rhel9-AppStream" +} +], +"set_id": 26179 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19572, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "gcc-toolset-15-gcc", +"repository": "rhel9-AppStream" +} +], +"set_id": 26180 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 4, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19573, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "cockpit-ws", +"repository": "rhel10-BaseOS" +} +], +"set_id": 26181 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "cockpit-ws", +"repository": "rhel10-BaseOS" +}, +{ +"modulestreams": [ +null +], +"name": "cockpit-ws-selinux", +"repository": "rhel10-BaseOS" +} +], +"set_id": 26182 +}, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"x86_64" +], +"id": 19574, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "eclipse", +"stream": "rhel8" +} +], +"name": "hamcrest-core", +"repository": "rhel8-AppStream" +} +], +"set_id": 26183 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"x86_64" +], +"id": 19575, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "eclipse", +"stream": "rhel8" +} +], +"name": "glassfish-servlet-api", +"repository": "rhel8-AppStream" +} +], +"set_id": 26184 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"x86_64" +], +"id": 19576, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "eclipse", +"stream": "rhel8" +} +], +"name": "glassfish-annotation-api", +"repository": "rhel8-AppStream" +} +], +"set_id": 26185 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"x86_64" +], +"id": 19577, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "eclipse", +"stream": "rhel8" +} +], +"name": "apache-commons-jxpath", +"repository": "rhel8-AppStream" +} +], +"set_id": 26186 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"x86_64" +], +"id": 19578, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "eclipse", +"stream": "rhel8" +} +], +"name": "glassfish-el", +"repository": "rhel8-AppStream" +} +], +"set_id": 26187 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 1, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19579, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "javapackages-tools", +"stream": "201801" +} +], +"name": "glassfish-el", +"repository": "rhel8-CRB" +} +], +"set_id": 26188 +}, +"initial_release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"x86_64" +], +"id": 19580, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "eclipse", +"stream": "rhel8" +} +], +"name": "glassfish-jsp-api", +"repository": "rhel8-AppStream" +} +], +"set_id": 26189 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 4, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19581, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "cockpit-ws", +"repository": "rhel9-BaseOS" +} +], +"set_id": 26190 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "cockpit-ws", +"repository": "rhel9-BaseOS" +}, +{ +"modulestreams": [ +null +], +"name": "cockpit-ws-selinux", +"repository": "rhel9-BaseOS" +} +], +"set_id": 26191 +}, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19582, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "jbig2dec-devel", +"repository": "rhel9-CRB" +} +], +"set_id": 26192 +}, +"initial_release": { +"major_version": 9, +"minor_version": 1, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 2, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19583, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "librabbitmq-tools", +"repository": "rhel8-AppStream" +} +], +"set_id": 26193 +}, +"initial_release": { +"major_version": 8, +"minor_version": 8, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19584, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "git-credential-libsecret", +"repository": "rhel8-AppStream" +} +], +"set_id": 26194 +}, +"initial_release": { +"major_version": 8, +"minor_version": 2, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 3, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19585, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "git-lfs", +"repository": "rhel8-AppStream" +} +], +"set_id": 26195 +}, +"initial_release": { +"major_version": 8, +"minor_version": 2, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 3, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"ppc64le" +], +"id": 19586, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "ppc64-diag-rtas", +"repository": "rhel8-BaseOS" +} +], +"set_id": 26196 +}, +"initial_release": { +"major_version": 8, +"minor_version": 2, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 3, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"ppc64le", +"s390x", +"x86_64" +], +"id": 19587, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "amanda", +"repository": "rhel7-base" +} +], +"set_id": 26197 +}, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "amanda", +"repository": "rhel8-AppStream" +} +], +"set_id": 26198 +}, +"release": { +"major_version": 8, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"ppc64le", +"s390x", +"x86_64" +], +"id": 19588, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "amanda-client", +"repository": "rhel7-base" +} +], +"set_id": 26199 +}, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "amanda-client", +"repository": "rhel8-AppStream" +} +], +"set_id": 26200 +}, +"release": { +"major_version": 8, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"ppc64le", +"s390x", +"x86_64" +], +"id": 19589, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "amanda-libs", +"repository": "rhel7-base" +} +], +"set_id": 26201 +}, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "amanda-libs", +"repository": "rhel8-AppStream" +} +], +"set_id": 26202 +}, +"release": { +"major_version": 8, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"x86_64" +], +"id": 19590, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "amanda-server", +"repository": "rhel7-optional" +} +], +"set_id": 26203 +}, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "amanda-server", +"repository": "rhel8-AppStream" +} +], +"set_id": 26204 +}, +"release": { +"major_version": 8, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"ppc64le", +"s390x", +"x86_64" +], +"id": 19591, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "amanda-server", +"repository": "rhel7-base" +} +], +"set_id": 26205 +}, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "amanda-server", +"repository": "rhel8-AppStream" +} +], +"set_id": 26206 +}, +"release": { +"major_version": 8, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"ppc64le", +"s390x", +"x86_64" +], +"id": 19592, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "asciidoc", +"repository": "rhel7-optional" +} +], +"set_id": 26207 +}, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "asciidoc", +"repository": "rhel8-AppStream" +} +], +"set_id": 26208 +}, +"release": { +"major_version": 8, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"ppc64le", +"s390x", +"x86_64" +], +"id": 19593, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "at", +"repository": "rhel7-base" +} +], +"set_id": 26209 +}, +"initial_release": { +"major_version": 7, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "at", +"repository": "rhel8-BaseOS" +} +], +"set_id": 26210 +}, +"release": { +"major_version": 8, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"x86_64" +], +"id": 19594, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "azure-vm-utils", +"repository": "rhel10-AppStream" +} +], +"set_id": 26213 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19595, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "gcc-toolset-15-binutils", +"repository": "rhel9-BaseOS" +} +], +"set_id": 26214 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19596, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "gcc-toolset-15-binutils", +"repository": "rhel10-BaseOS" +} +], +"set_id": 26215 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19597, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "gcc-plugin-devel", +"repository": "rhel9-CRB" +} +], +"set_id": 26216 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "gcc-plugin-devel", +"repository": "rhel9-AppStream" +} +], +"set_id": 26217 +}, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19598, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "gcc-plugin-devel", +"repository": "rhel10-CRB" +} +], +"set_id": 26222 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "gcc-plugin-devel", +"repository": "rhel10-AppStream" +} +], +"set_id": 26223 +}, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 1, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19599, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "SDL2", +"repository": "rhel9-AppStream" +} +], +"set_id": 26220 +}, +"initial_release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19600, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "SDL2", +"repository": "rhel9-AppStream" +} +], +"set_id": 26221 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"x86_64" +], +"id": 19601, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "azure-vm-utils", +"repository": "rhel9-AppStream" +} +], +"set_id": 26224 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19602, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "gcc-toolset-15", +"repository": "rhel10-AppStream" +} +], +"set_id": 26225 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19603, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "valkey", +"repository": "rhel9-AppStream" +} +], +"set_id": 26226 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19604, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "valkey-devel", +"repository": "rhel9-AppStream" +} +], +"set_id": 26227 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19605, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "gcc-toolset-15-gcc", +"repository": "rhel10-AppStream" +} +], +"set_id": 26228 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19606, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-rpm-macros", +"repository": "rhel9-CRB" +} +], +"set_id": 26229 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19607, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-rpm-macros", +"repository": "rhel10-CRB" +} +], +"set_id": 26230 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 7, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19608, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "llvm-toolset", +"stream": "rhel8" +} +], +"name": "python3-lit", +"repository": "rhel8-AppStream" +} +], +"set_id": 26231 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "llvm-toolset", +"stream": "rhel8" +}, +"out_modulestream": { +"name": "llvm-toolset", +"stream": "rhel8" +} +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "llvm-toolset", +"stream": "rhel8" +} +], +"name": "python3.12-lit", +"repository": "rhel8-AppStream" +} +], +"set_id": 26232 +}, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 7, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19609, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "llvm-toolset", +"stream": "rhel8" +} +], +"name": "python3.12-lit", +"repository": "rhel8-AppStream" +} +], +"set_id": 26233 +}, +"initial_release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "llvm-toolset", +"stream": "rhel8" +}, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "python3-lit", +"repository": "rhel9-AppStream" +} +], +"set_id": 26234 +}, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 7, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19610, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "llvm-toolset", +"stream": "rhel8" +} +], +"name": "python3-lldb", +"repository": "rhel8-AppStream" +} +], +"set_id": 26235 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "llvm-toolset", +"stream": "rhel8" +}, +"out_modulestream": { +"name": "llvm-toolset", +"stream": "rhel8" +} +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "llvm-toolset", +"stream": "rhel8" +} +], +"name": "python3.12-lldb", +"repository": "rhel8-AppStream" +} +], +"set_id": 26236 +}, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 7, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19611, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "llvm-toolset", +"stream": "rhel8" +} +], +"name": "python3.12-lldb", +"repository": "rhel8-AppStream" +} +], +"set_id": 26237 +}, +"initial_release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "llvm-toolset", +"stream": "rhel8" +}, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "python3-lldb", +"repository": "rhel9-AppStream" +} +], +"set_id": 26238 +}, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 7, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19612, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "llvm-toolset", +"stream": "rhel8" +} +], +"name": "python3.12-clang", +"repository": "rhel8-AppStream" +} +], +"set_id": 26239 +}, +"initial_release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "llvm-toolset", +"stream": "rhel8" +}, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "python3-clang", +"repository": "rhel9-AppStream" +} +], +"set_id": 26240 +}, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 7, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19613, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "llvm-toolset", +"stream": "rhel8" +} +], +"name": "python3-clang", +"repository": "rhel8-AppStream" +} +], +"set_id": 26241 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "llvm-toolset", +"stream": "rhel8" +}, +"out_modulestream": { +"name": "llvm-toolset", +"stream": "rhel8" +} +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "llvm-toolset", +"stream": "rhel8" +} +], +"name": "python3.12-clang", +"repository": "rhel8-AppStream" +} +], +"set_id": 26242 +}, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19614, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "llvm-toolset", +"stream": "rhel8" +} +], +"name": "python3-clang", +"repository": "rhel8-AppStream" +} +], +"set_id": 26243 +}, +"initial_release": { +"major_version": 8, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 7, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19615, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "libpeas", +"repository": "rhel9-BaseOS" +} +], +"set_id": 26244 +}, +"initial_release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": null, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "libpeas1", +"repository": "rhel10-BaseOS" +} +], +"set_id": 26245 +}, +"release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19616, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "libwebp-tools", +"repository": "rhel8-CRB" +} +], +"set_id": 26246 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19617, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-enclave-prebuilt-common", +"repository": "rhel9-AppStream" +} +], +"set_id": 26247 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19618, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-enclave-prebuilt-ide-signed", +"repository": "rhel9-AppStream" +} +], +"set_id": 26248 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19619, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-enclave-prebuilt-pce-signed", +"repository": "rhel9-AppStream" +} +], +"set_id": 26249 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19620, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-enclave-prebuilt-tdqe-signed", +"repository": "rhel9-AppStream" +} +], +"set_id": 26250 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19621, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-common", +"repository": "rhel9-AppStream" +} +], +"set_id": 26251 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19622, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-libs", +"repository": "rhel9-AppStream" +} +], +"set_id": 26252 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19623, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-mpa", +"repository": "rhel9-AppStream" +} +], +"set_id": 26253 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19624, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-pckid-tool", +"repository": "rhel9-AppStream" +} +], +"set_id": 26254 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19625, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "tdx-qgs", +"repository": "rhel9-AppStream" +} +], +"set_id": 26255 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19626, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-common", +"repository": "rhel10-AppStream" +} +], +"set_id": 26256 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19627, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-libs", +"repository": "rhel10-AppStream" +} +], +"set_id": 26257 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19628, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-mpa", +"repository": "rhel10-AppStream" +} +], +"set_id": 26258 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19629, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-pckid-tool", +"repository": "rhel10-AppStream" +} +], +"set_id": 26259 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19630, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "tdx-qgs", +"repository": "rhel10-AppStream" +} +], +"set_id": 26260 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19631, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-enclave-prebuilt-common", +"repository": "rhel10-AppStream" +} +], +"set_id": 26261 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19632, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-enclave-prebuilt-ide-signed", +"repository": "rhel10-AppStream" +} +], +"set_id": 26262 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19633, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-enclave-prebuilt-pce-signed", +"repository": "rhel10-AppStream" +} +], +"set_id": 26263 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"x86_64" +], +"id": 19634, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sgx-enclave-prebuilt-tdqe-signed", +"repository": "rhel10-AppStream" +} +], +"set_id": 26264 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"ppc64le", +"x86_64" +], +"id": 19635, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sap-hana-ha", +"repository": "rhel9-SAP-Solutions" +} +], +"set_id": 26265 +}, +"initial_release": { +"major_version": 9, +"minor_version": 3, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 4, +"os_name": "RHEL" +} +}, +{ +"action": 1, +"architectures": [ +"ppc64le", +"x86_64" +], +"id": 19636, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "sap-hana-ha", +"repository": "rhel9-SAP-Solutions" +} +], +"set_id": 26266 +}, +"initial_release": { +"major_version": 9, +"minor_version": 4, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 5, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19637, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "fips-provider-next", +"repository": "rhel9-AppStream" +} +], +"set_id": 26267 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19638, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "insights-core-selinux", +"repository": "rhel10-AppStream" +} +], +"set_id": 26268 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19639, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "insights-core-selinux", +"repository": "rhel9-AppStream" +} +], +"set_id": 26269 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19640, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "lftp", +"repository": "rhel10-AppStream" +} +], +"set_id": 26270 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19641, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "ftp", +"repository": "rhel10-AppStream" +} +], +"set_id": 26271 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19642, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "vsftpd", +"repository": "rhel10-AppStream" +} +], +"set_id": 26272 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19643, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "hunspell-ka", +"repository": "rhel10-AppStream" +} +], +"set_id": 26273 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 6, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19644, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "php", +"stream": "7.4" +}, +{ +"name": "php", +"stream": "8.0" +} +], +"name": "php-ffi", +"repository": "rhel8-AppStream" +} +], +"set_id": 26274 +}, +"initial_release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +}, +"modulestream_maps": [ +{ +"in_modulestream": { +"name": "php", +"stream": "7.4" +}, +"out_modulestream": null +}, +{ +"in_modulestream": { +"name": "php", +"stream": "8.0" +}, +"out_modulestream": null +} +], +"out_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "php-ffi", +"repository": "rhel9-AppStream" +} +], +"set_id": 26275 +}, +"release": { +"major_version": 9, +"minor_version": 0, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19645, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "php", +"stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +} +], +"name": "php-json", +"repository": "rhel8-AppStream" +} +], +"set_id": 26276 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19646, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "php", +"stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +} +], +"name": "php-recode", +"repository": "rhel8-AppStream" +} +], +"set_id": 26277 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 2, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19647, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +{ +"name": "php", +"stream": "7.2" +}, +{ +"name": "php", +"stream": "7.3" +}, +{ +"name": "php", +"stream": "7.4" +} +], +"name": "php-xmlrpc", +"repository": "rhel8-AppStream" +} +], +"set_id": 26278 +}, +"initial_release": { +"major_version": 8, +"minor_version": 9, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 8, +"minor_version": 10, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19648, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "perl-XS-Parse-Keyword-Builder", +"repository": "rhel10-CRB" +} +], +"set_id": 26279 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19649, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "bindgen-cli", +"repository": "rhel10-CRB" +} +], +"set_id": 26280 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19650, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "bindgen-cli", +"repository": "rhel9-CRB" +} +], +"set_id": 26281 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19651, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "cbindgen", +"repository": "rhel10-CRB" +} +], +"set_id": 26282 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19652, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "cbindgen", +"repository": "rhel9-CRB" +} +], +"set_id": 26283 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19653, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "image-builder", +"repository": "rhel10-AppStream" +} +], +"set_id": 26284 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19654, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "image-builder", +"repository": "rhel9-AppStream" +} +], +"set_id": 26285 +}, +"initial_release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 7, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19655, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "fips-provider-next", +"repository": "rhel10-AppStream" +} +], +"set_id": 26286 +}, +"initial_release": { +"major_version": 10, +"minor_version": 0, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 10, +"minor_version": 1, +"os_name": "RHEL" +} +}, +{ +"action": 0, +"architectures": [ +"aarch64", +"ppc64le", +"s390x", +"x86_64" +], +"id": 19656, +"in_packageset": { +"package": [ +{ +"modulestreams": [ +null +], +"name": "redhat-cloud-client-configuration-cdn", +"repository": "rhel9-AppStream" +} +], +"set_id": 26287 +}, +"initial_release": { +"major_version": 9, +"minor_version": 5, +"os_name": "RHEL" +}, +"modulestream_maps": [], +"out_packageset": null, +"release": { +"major_version": 9, +"minor_version": 6, +"os_name": "RHEL" +} } ] } diff --git a/etc/leapp/files/repomap.json b/etc/leapp/files/repomap.json index 0cd5601a..87646393 100644 --- a/etc/leapp/files/repomap.json +++ b/etc/leapp/files/repomap.json @@ -1,5 +1,5 @@ { - "datetime": "202507171303Z", + "datetime": "202508131404Z", "version_format": "1.3.0", "provided_data_streams": [ "4.0" @@ -312,6 +312,24 @@ "target": [ "rhel10-rhui-custom-client-at-alibaba" ] + }, + { + "source": "rhel9-rhui-client-config-server-9-sap", + "target": [ + "rhel10-rhui-client-config-server-10-sap" + ] + }, + { + "source": "rhel9-rhui-microsoft-azure-sap-apps", + "target": [ + "rhel10-rhui-microsoft-azure-sap-apps" + ] + }, + { + "source": "rhel9-rhui-microsoft-sap-ha", + "target": [ + "rhel10-rhui-microsoft-sap-ha" + ] } ] } @@ -501,6 +519,15 @@ "distro": "rhel", "rhui": "aws" }, + { + "major_version": "10", + "repoid": "rhel-10-for-x86_64-baseos-e4s-rhui-rpms", + "arch": "x86_64", + "channel": "e4s", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "azure" + }, { "major_version": "10", "repoid": "rhel-10-for-x86_64-baseos-e4s-rpms", @@ -509,6 +536,15 @@ "repo_type": "rpm", "distro": "rhel" }, + { + "major_version": "10", + "repoid": "rhel-10-for-x86_64-baseos-eus-rhui-rpms", + "arch": "x86_64", + "channel": "eus", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "azure" + }, { "major_version": "10", "repoid": "rhel-10-for-x86_64-baseos-eus-rpms", @@ -729,6 +765,15 @@ "distro": "rhel", "rhui": "aws" }, + { + "major_version": "10", + "repoid": "rhel-10-for-x86_64-appstream-e4s-rhui-rpms", + "arch": "x86_64", + "channel": "e4s", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "azure" + }, { "major_version": "10", "repoid": "rhel-10-for-x86_64-appstream-e4s-rpms", @@ -737,6 +782,15 @@ "repo_type": "rpm", "distro": "rhel" }, + { + "major_version": "10", + "repoid": "rhel-10-for-x86_64-appstream-eus-rhui-rpms", + "arch": "x86_64", + "channel": "eus", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "azure" + }, { "major_version": "10", "repoid": "rhel-10-for-x86_64-appstream-eus-rpms", @@ -1303,6 +1357,15 @@ "distro": "rhel", "rhui": "aws" }, + { + "major_version": "10", + "repoid": "rhel-10-for-x86_64-sap-netweaver-e4s-rhui-rpms", + "arch": "x86_64", + "channel": "e4s", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "azure" + }, { "major_version": "10", "repoid": "rhel-10-for-x86_64-sap-netweaver-e4s-rpms", @@ -1311,6 +1374,15 @@ "repo_type": "rpm", "distro": "rhel" }, + { + "major_version": "10", + "repoid": "rhel-10-for-x86_64-sap-netweaver-eus-rhui-rpms", + "arch": "x86_64", + "channel": "eus", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "azure" + }, { "major_version": "10", "repoid": "rhel-10-for-x86_64-sap-netweaver-eus-rpms", @@ -1357,6 +1429,15 @@ "distro": "rhel", "rhui": "aws" }, + { + "major_version": "10", + "repoid": "rhel-10-for-x86_64-sap-solutions-e4s-rhui-rpms", + "arch": "x86_64", + "channel": "e4s", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "azure" + }, { "major_version": "10", "repoid": "rhel-10-for-x86_64-sap-solutions-e4s-rpms", @@ -1523,6 +1604,15 @@ "distro": "rhel", "rhui": "aws" }, + { + "major_version": "10", + "repoid": "rhel-10-for-x86_64-highavailability-e4s-rhui-rpms", + "arch": "x86_64", + "channel": "e4s", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "azure" + }, { "major_version": "10", "repoid": "rhel-10-for-x86_64-highavailability-e4s-rpms", @@ -1618,6 +1708,48 @@ } ] }, + { + "pesid": "rhel10-rhui-client-config-server-10-sap", + "entries": [ + { + "major_version": "10", + "repoid": "rhui-client-config-server-10-sap-bundle", + "arch": "x86_64", + "channel": "ga", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "aws" + } + ] + }, + { + "pesid": "rhel10-rhui-microsoft-azure-sap-apps", + "entries": [ + { + "major_version": "10", + "repoid": "rhui-microsoft-azure-rhel10-sapapps", + "arch": "x86_64", + "channel": "eus", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "azure" + } + ] + }, + { + "pesid": "rhel10-rhui-microsoft-sap-ha", + "entries": [ + { + "major_version": "10", + "repoid": "rhui-microsoft-azure-rhel10-sap-ha", + "arch": "x86_64", + "channel": "e4s", + "repo_type": "rpm", + "distro": "rhel", + "rhui": "azure" + } + ] + }, { "pesid": "rhel7-base", "entries": [ @@ -4166,6 +4298,14 @@ "repo_type": "rpm", "distro": "rhel" }, + { + "major_version": "8", + "repoid": "rhel-8-for-x86_64-highavailability-aus-rpms", + "arch": "x86_64", + "channel": "aus", + "repo_type": "rpm", + "distro": "rhel" + }, { "major_version": "8", "repoid": "rhel-8-for-x86_64-highavailability-beta-rpms", diff --git a/etc/leapp/transaction/to_reinstall b/etc/leapp/transaction/to_reinstall new file mode 100644 index 00000000..c6694a8e --- /dev/null +++ b/etc/leapp/transaction/to_reinstall @@ -0,0 +1,3 @@ +### List of packages (each on new line) to be reinstalled to the upgrade transaction +### Useful for packages that have identical version strings but contain binary changes between major OS versions +### Packages that aren't installed will be skipped diff --git a/packaging/leapp-repository.spec b/packaging/leapp-repository.spec index 34768de1..6d96d665 100644 --- a/packaging/leapp-repository.spec +++ b/packaging/leapp-repository.spec @@ -130,6 +130,10 @@ Requires: leapp # uncompressing redhat-release package from the ISO. Requires: cpio +# Subpackage for managing fapolicyd rules for %{lpr_name} installed only if +# fapolicyd is present on the system +Requires: (%{lpr_name}-fapolicyd = %{version}-%{release} if fapolicyd) + # The leapp-repository rpm is renamed to %%{lpr_name} Obsoletes: leapp-repository < 0.14.0-%{release} Provides: leapp-repository = %{version}-%{release} @@ -227,6 +231,15 @@ Requires: libdb-utils %{summary} +%package -n %{lpr_name}-fapolicyd +Summary: Manage fapolicyd rules for %{lpr_name} during the upgrade + +Requires: fapolicyd + +%description -n %{lpr_name}-fapolicyd +%{summary} + + %prep %setup -n %{name}-%{version} %setup -q -n %{name}-%{version} -D -T -a 1 @@ -250,6 +263,10 @@ install -m 0755 -d %{buildroot}%{_sysconfdir}/leapp/files/ install -m 0644 etc/leapp/transaction/* %{buildroot}%{_sysconfdir}/leapp/transaction install -m 0644 etc/leapp/files/* %{buildroot}%{_sysconfdir}/leapp/files +# install rules necessary for fapolicy +mkdir -p %{buildroot}%{_sysconfdir}/fapolicyd/rules.d/ +install -m 0644 etc/fapolicyd/rules.d/31-leapp-repository.rules %{buildroot}%{_sysconfdir}/fapolicyd/rules.d + # uncomment to install existing configs if any exists #install -m 0644 etc/leapp/actor_conf.d/* %%{buildroot}%%{_sysconfdir}/leapp/actor_conf.d @@ -291,6 +308,12 @@ done; %endif +%posttrans -n %{lpr_name}-fapolicyd +if systemctl is-active --quiet fapolicyd; then + systemctl restart fapolicyd +fi + + %files -n %{lpr_name} %doc README.md %license LICENSE @@ -313,6 +336,9 @@ done; # no files here +%files -n %{lpr_name}-fapolicyd +%attr(644, root, fapolicyd) %config %{_sysconfdir}/fapolicyd/rules.d/31-leapp-repository.rules + # DO NOT TOUCH SECTION BELOW IN UPSTREAM %changelog * Mon Apr 16 2018 Vinzenz Feenstra - %{version}-%{release} diff --git a/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py b/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py index b28ec57c..6882488a 100644 --- a/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py +++ b/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py @@ -91,7 +91,7 @@ def figure_out_commands_needed_to_add_entry(kernel_path, initramfs_path, args_to '/usr/sbin/grubby', '--add-kernel', '{0}'.format(kernel_path), '--initrd', '{0}'.format(initramfs_path), - '--title', 'RHEL-Upgrade-Initramfs', + '--title', 'ELevate-Upgrade-Initramfs', '--copy-default', '--make-default', '--args', args_to_add_str diff --git a/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py b/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py index e5f632bc..3e8d8c7b 100644 --- a/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py +++ b/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py @@ -53,7 +53,7 @@ run_args_add = [ '/usr/sbin/grubby', '--add-kernel', '/abc', '--initrd', '/def', - '--title', 'RHEL-Upgrade-Initramfs', + '--title', 'ELevate-Upgrade-Initramfs', '--copy-default', '--make-default', '--args', diff --git a/repos/system_upgrade/common/actors/checkenabledvendorrepos/actor.py b/repos/system_upgrade/common/actors/checkenabledvendorrepos/actor.py new file mode 100644 index 00000000..52f5af9d --- /dev/null +++ b/repos/system_upgrade/common/actors/checkenabledvendorrepos/actor.py @@ -0,0 +1,53 @@ +from leapp.actors import Actor +from leapp.libraries.stdlib import api +from leapp.models import ( + RepositoriesFacts, + VendorSourceRepos, + ActiveVendorList, +) +from leapp.tags import FactsPhaseTag, IPUWorkflowTag + + +class CheckEnabledVendorRepos(Actor): + """ + Create a list of vendors whose repositories are present on the system and enabled. + Only those vendors' configurations (new repositories, PES actions, etc.) + will be included in the upgrade process. + """ + + name = "check_enabled_vendor_repos" + consumes = (RepositoriesFacts, VendorSourceRepos) + produces = (ActiveVendorList) + tags = (IPUWorkflowTag, FactsPhaseTag.Before) + + def process(self): + vendor_mapping_data = {} + active_vendors = set() + + # Make a dict for easy mapping of repoid -> corresponding vendor name. + for vendor_src_repodata in api.consume(VendorSourceRepos): + for vendor_src_repo in vendor_src_repodata.source_repoids: + vendor_mapping_data[vendor_src_repo] = vendor_src_repodata.vendor + + # Is the repo listed in the vendor map as from_repoid present on the system? + for repos_facts in api.consume(RepositoriesFacts): + for repo_file in repos_facts.repositories: + for repo_data in repo_file.data: + self.log.debug( + "Looking for repository {} in vendor maps".format(repo_data.repoid) + ) + if repo_data.enabled and repo_data.repoid in vendor_mapping_data: + # If the vendor's repository is present in the system and enabled, count the vendor as active. + new_vendor = vendor_mapping_data[repo_data.repoid] + self.log.debug( + "Repository {} found and enabled, enabling vendor {}".format( + repo_data.repoid, new_vendor + ) + ) + active_vendors.add(new_vendor) + + if active_vendors: + self.log.debug("Active vendor list: {}".format(active_vendors)) + api.produce(ActiveVendorList(data=list(active_vendors))) + else: + self.log.info("No active vendors found, vendor list not generated") diff --git a/repos/system_upgrade/common/actors/checkleftoverpackages/actor.py b/repos/system_upgrade/common/actors/checkleftoverpackages/actor.py index a4e32923..e60075a6 100644 --- a/repos/system_upgrade/common/actors/checkleftoverpackages/actor.py +++ b/repos/system_upgrade/common/actors/checkleftoverpackages/actor.py @@ -1,6 +1,6 @@ from leapp.actors import Actor from leapp.libraries.actor import checkleftoverpackages -from leapp.models import InstalledUnsignedRPM, LeftoverPackages, TransactionCompleted +from leapp.models import LeftoverPackages, ThirdPartyRPM, TransactionCompleted from leapp.tags import IPUWorkflowTag, RPMUpgradePhaseTag @@ -13,7 +13,7 @@ class CheckLeftoverPackages(Actor): """ name = 'check_leftover_packages' - consumes = (TransactionCompleted, InstalledUnsignedRPM) + consumes = (TransactionCompleted, ThirdPartyRPM) produces = (LeftoverPackages,) tags = (RPMUpgradePhaseTag, IPUWorkflowTag) diff --git a/repos/system_upgrade/common/actors/checkleftoverpackages/libraries/checkleftoverpackages.py b/repos/system_upgrade/common/actors/checkleftoverpackages/libraries/checkleftoverpackages.py index 83160f1b..75c1e91e 100644 --- a/repos/system_upgrade/common/actors/checkleftoverpackages/libraries/checkleftoverpackages.py +++ b/repos/system_upgrade/common/actors/checkleftoverpackages/libraries/checkleftoverpackages.py @@ -3,7 +3,7 @@ import re from leapp.libraries.common.config.version import get_source_major_version from leapp.libraries.common.rpms import get_installed_rpms, get_leapp_dep_packages, get_leapp_packages from leapp.libraries.stdlib import api -from leapp.models import InstalledUnsignedRPM, LeftoverPackages, RPM +from leapp.models import LeftoverPackages, RPM, ThirdPartyRPM def process(): @@ -15,7 +15,7 @@ def process(): return leftover_pkgs_to_remove = [] - unsigned = [pkg.name for pkg in next(api.consume(InstalledUnsignedRPM), InstalledUnsignedRPM()).items] + unsigned = [pkg.name for pkg in next(api.consume(ThirdPartyRPM), ThirdPartyRPM()).items] for rpm in installed_rpms: rpm = rpm.strip() diff --git a/repos/system_upgrade/common/actors/checkleftoverpackages/tests/test_checkleftoverpackages.py b/repos/system_upgrade/common/actors/checkleftoverpackages/tests/test_checkleftoverpackages.py index 75e0120c..33c16a96 100644 --- a/repos/system_upgrade/common/actors/checkleftoverpackages/tests/test_checkleftoverpackages.py +++ b/repos/system_upgrade/common/actors/checkleftoverpackages/tests/test_checkleftoverpackages.py @@ -3,7 +3,7 @@ import pytest from leapp.libraries.actor import checkleftoverpackages from leapp.libraries.common.testutils import CurrentActorMocked, produce_mocked from leapp.libraries.stdlib import api -from leapp.models import InstalledUnsignedRPM, LeftoverPackages, RPM +from leapp.models import LeftoverPackages, RPM, ThirdPartyRPM @pytest.mark.parametrize( @@ -44,7 +44,7 @@ def test_package_to_be_removed(monkeypatch, source_major_version, rpm_name, rele UnsignedRPM = RPM(name='unsigned', version='0.1', release=release, epoch='0', packager='packager', arch='noarch', pgpsig='OTHER_SIG') - monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=[InstalledUnsignedRPM(items=[UnsignedRPM])])) + monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=[ThirdPartyRPM(items=[UnsignedRPM])])) monkeypatch.setattr(checkleftoverpackages, 'get_installed_rpms', get_installed_rpms_mocked) monkeypatch.setattr(checkleftoverpackages, 'get_source_major_version', lambda: str(source_major_version)) monkeypatch.setattr(api, 'produce', produce_mocked()) diff --git a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/do-upgrade.sh b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/do-upgrade.sh index 56a94b5d..46c5d9b6 100755 --- a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/do-upgrade.sh +++ b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/do-upgrade.sh @@ -390,4 +390,3 @@ getarg 'rd.break=leapp-logs' 'rd.upgrade.break=leapp-finish' && { sync mount -o "remount,$old_opts" "$NEWROOT" exit $result - diff --git a/repos/system_upgrade/common/actors/distributionsignedrpmcheck/actor.py b/repos/system_upgrade/common/actors/distributionsignedrpmcheck/actor.py new file mode 100644 index 00000000..de558a48 --- /dev/null +++ b/repos/system_upgrade/common/actors/distributionsignedrpmcheck/actor.py @@ -0,0 +1,36 @@ +from leapp.actors import Actor +from leapp.libraries.actor.distributionsignedrpmcheck import check_third_party_pkgs +from leapp.models import ThirdPartyRPM +from leapp.reporting import Report +from leapp.tags import ChecksPhaseTag, IPUWorkflowTag + + +class DistributionSignedRpmCheck(Actor): + """ + Check if there are any packages that are not signed by distribution GPG keys. + + We are recognizing two (three) types of packages: + * Distribution packages - RPMs that are part of the system distribution (RHEL, + Centos Stream, Fedora, ...) - which are recognized based on the signature + by known GPG keys for the particular distribution. + * Third-party packages - RPMs that are not signed by such GPG keys - + including RPMs not signed at all. Such RPMs are considered in general as + third party content. + ( + * some packages are known to not be signed as they are created by + delivered product (which can be part of the distribution). This includes + e.g. katello RPMs created in a Satellite server. We do not report + such packages known to us. + ) + + All such third-party installed packages are reported to inform the user to + take care of them before, during or after the upgrade. + """ + + name = 'distribution_signed_rpm_check' + consumes = (ThirdPartyRPM,) + produces = (Report,) + tags = (IPUWorkflowTag, ChecksPhaseTag) + + def process(self): + check_third_party_pkgs() diff --git a/repos/system_upgrade/common/actors/distributionsignedrpmcheck/libraries/distributionsignedrpmcheck.py b/repos/system_upgrade/common/actors/distributionsignedrpmcheck/libraries/distributionsignedrpmcheck.py new file mode 100644 index 00000000..1c0df635 --- /dev/null +++ b/repos/system_upgrade/common/actors/distributionsignedrpmcheck/libraries/distributionsignedrpmcheck.py @@ -0,0 +1,80 @@ +from leapp import reporting +from leapp.libraries.stdlib import api +from leapp.libraries.stdlib.config import is_verbose +from leapp.models import ThirdPartyRPM + +FMT_LIST_SEPARATOR = "\n - " + + +def _generate_report(packages): + """Generate a report with installed packages not signed by the distribution""" + + if not packages: + return + + title = "Packages not signed by the distribution vendor found on the system" + summary = ( + "The official solution for in-place upgrades contains instructions for" + " the migration of packages signed by the vendor of the system" + " distribution. Third-party content is not known to the upgrade" + " process and it might need to be handled extra." + " Third-party packages may be removed automatically during the upgrade if" + " they depend on official distribution content which is not present on" + " the target system - therefore RPM dependencies of such packages" + " cannot be satisfied and hence such packages cannot be installed on" + " the target system.\n\n" + "The following packages have not been signed by the vendor of the" + " distribution:{}{}" + ).format(FMT_LIST_SEPARATOR, FMT_LIST_SEPARATOR.join(packages)) + hint = ( + "The most simple solution that does not require additional knowledge" + " about the upgrade process is the uninstallation of such packages" + " before the upgrade and installing these (or their newer versions" + " compatible with the target system) back after the upgrade. Also you" + " can just try to upgrade the system on a testing machine (or after" + " the full system backup) to see the result.\n" + "However, it is common use case to migrate or upgrade installed third" + " party packages together with the system during the in-place upgrade" + " process. To examine how to customize the process to deal with such" + " packages, follow the documentation in the attached link" + " for more details." + ) + reporting.create_report( + [ + reporting.Title(title), + reporting.Summary(summary), + reporting.Severity(reporting.Severity.HIGH), + reporting.Groups([reporting.Groups.SANITY]), + reporting.Remediation(hint=hint), + reporting.ExternalLink( + url="https://red.ht/customize-rhel-upgrade-actors", + title="Handling the migration of your custom and third-party applications", + ), + # setting a stable key of the original, semantically equal, report + # which was concerned with RHEL only + reporting.Key("13f0791ae5f19f50e7d0d606fb6501f91b1efb2c") + ] + ) + + if is_verbose(): + api.show_message(summary) + + +def get_third_party_pkgs(): + """Get a list of installed packages not signed by the distribution""" + + rpm_messages = api.consume(ThirdPartyRPM) + data = next(rpm_messages, ThirdPartyRPM()) + if list(rpm_messages): + api.current_logger().warning( + "Unexpectedly received more than one ThirdPartyRPM message." + ) + + third_party_pkgs = list(set(pkg.name for pkg in data.items)) + third_party_pkgs.sort() + return third_party_pkgs + + +def check_third_party_pkgs(): + """Check and generate a report if the system contains third-party installed packages""" + _generate_report(get_third_party_pkgs()) diff --git a/repos/system_upgrade/common/actors/distributionsignedrpmcheck/tests/test_distributionsignedrpmcheck.py b/repos/system_upgrade/common/actors/distributionsignedrpmcheck/tests/test_distributionsignedrpmcheck.py new file mode 100644 index 00000000..54271409 --- /dev/null +++ b/repos/system_upgrade/common/actors/distributionsignedrpmcheck/tests/test_distributionsignedrpmcheck.py @@ -0,0 +1,81 @@ +from leapp import reporting +from leapp.libraries.actor import distributionsignedrpmcheck +from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked +from leapp.libraries.stdlib import api +from leapp.models import RPM, ThirdPartyRPM + +RH_PACKAGER = 'Red Hat, Inc. ' + + +def test_actor_execution_without_third_party_pkgs(monkeypatch): + third_party_rpm = ThirdPartyRPM(items=[]) + monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=[third_party_rpm])) + monkeypatch.setattr(api, "show_message", lambda x: True) + monkeypatch.setattr(reporting, "create_report", create_report_mocked()) + + packages = distributionsignedrpmcheck.get_third_party_pkgs() + + assert not packages + distributionsignedrpmcheck._generate_report(packages) + assert reporting.create_report.called == 0 + + +def test_actor_execution_with_third_party_pkgs(monkeypatch): + installed_rpm = ThirdPartyRPM( + items=[ + RPM( + name="sample02", + version="0.1", + release="1.sm01", + epoch="1", + packager=RH_PACKAGER, + arch="noarch", + pgpsig="SOME_OTHER_SIG_X", + ), + RPM( + name="sample04", + version="0.1", + release="1.sm01", + epoch="1", + packager=RH_PACKAGER, + arch="noarch", + pgpsig="SOME_OTHER_SIG_X", + ), + RPM( + name="sample06", + version="0.1", + release="1.sm01", + epoch="1", + packager=RH_PACKAGER, + arch="noarch", + pgpsig="SOME_OTHER_SIG_X", + ), + RPM( + name="sample08", + version="0.1", + release="1.sm01", + epoch="1", + packager=RH_PACKAGER, + arch="noarch", + pgpsig="SOME_OTHER_SIG_X", + ), + ] + ) + monkeypatch.setattr(api, "current_actor", CurrentActorMocked(msgs=[installed_rpm])) + monkeypatch.setattr(api, "show_message", lambda x: True) + monkeypatch.setattr(reporting, "create_report", create_report_mocked()) + + packages = distributionsignedrpmcheck.get_third_party_pkgs() + assert len(packages) == 4 + distributionsignedrpmcheck._generate_report(packages) + + assert reporting.create_report.called == 1 + assert ( + "Packages not signed by the distribution vendor found on the system" + in reporting.create_report.report_fields["title"] + ) + # the key of the pre-generalization, original RHEL focused report + assert ( + reporting.create_report.report_fields["key"] + == "13f0791ae5f19f50e7d0d606fb6501f91b1efb2c" + ) diff --git a/repos/system_upgrade/common/actors/distributionsignedrpmscanner/actor.py b/repos/system_upgrade/common/actors/distributionsignedrpmscanner/actor.py index 56016513..9e7bbf4a 100644 --- a/repos/system_upgrade/common/actors/distributionsignedrpmscanner/actor.py +++ b/repos/system_upgrade/common/actors/distributionsignedrpmscanner/actor.py @@ -1,14 +1,14 @@ from leapp.actors import Actor from leapp.libraries.actor import distributionsignedrpmscanner -from leapp.models import DistributionSignedRPM, InstalledRedHatSignedRPM, InstalledRPM, InstalledUnsignedRPM +from leapp.models import DistributionSignedRPM, InstalledRPM, InstalledUnsignedRPM, ThirdPartyRPM, VendorSignatures from leapp.tags import FactsPhaseTag, IPUWorkflowTag from leapp.utils.deprecation import suppress_deprecation -@suppress_deprecation(InstalledRedHatSignedRPM) +@suppress_deprecation(InstalledUnsignedRPM) class DistributionSignedRpmScanner(Actor): """ - Provide data about distribution signed & unsigned RPM packages. + Provide data about distribution signed & third-party plus vendors RPM packages. For various checks and actions done during the upgrade it's important to know what packages are signed by GPG keys of the installed linux system @@ -22,12 +22,19 @@ class DistributionSignedRpmScanner(Actor): common/files/distro//gpg_signatures.json where is distribution ID of the installed system (e.g. centos, rhel). + Fingerprints of vendors GPG keys are stored under + /etc/leapp/files/vendors.d/.sigs + where is name of the vendor (e.g. mariadb, postgresql). + + The "Distribution" in the name of the actor is a historical artifact - the actor + is used for both distribution and all vendors present in config files. + If the file for the installed distribution is not find, end with error. """ name = 'distribution_signed_rpm_scanner' - consumes = (InstalledRPM,) - produces = (DistributionSignedRPM, InstalledRedHatSignedRPM, InstalledUnsignedRPM,) + consumes = (InstalledRPM, VendorSignatures) + produces = (DistributionSignedRPM, InstalledUnsignedRPM, ThirdPartyRPM) tags = (IPUWorkflowTag, FactsPhaseTag) def process(self): diff --git a/repos/system_upgrade/common/actors/distributionsignedrpmscanner/libraries/distributionsignedrpmscanner.py b/repos/system_upgrade/common/actors/distributionsignedrpmscanner/libraries/distributionsignedrpmscanner.py index 51d6eeb5..18c859e2 100644 --- a/repos/system_upgrade/common/actors/distributionsignedrpmscanner/libraries/distributionsignedrpmscanner.py +++ b/repos/system_upgrade/common/actors/distributionsignedrpmscanner/libraries/distributionsignedrpmscanner.py @@ -2,7 +2,8 @@ from leapp.libraries.common import rhui from leapp.libraries.common.config import get_env from leapp.libraries.common.distro import get_distribution_data from leapp.libraries.stdlib import api -from leapp.models import DistributionSignedRPM, InstalledRedHatSignedRPM, InstalledRPM, InstalledUnsignedRPM +from leapp.models import DistributionSignedRPM, InstalledRPM, InstalledUnsignedRPM, ThirdPartyRPM +from leapp.utils.deprecation import suppress_deprecation def is_distro_signed(pkg, distro_keys): @@ -29,6 +30,7 @@ def is_exceptional(pkg, allowlist): return pkg.name == 'gpg-pubkey' or pkg.name.startswith('katello-ca-consumer') or pkg.name in allowlist +@suppress_deprecation(InstalledUnsignedRPM) def process(): distribution = api.current_actor().configuration.os_release.release_id distro_keys = get_distribution_data(distribution).get('keys', []) @@ -36,18 +38,17 @@ def process(): rhui_pkgs = rhui.get_all_known_rhui_pkgs_for_current_upg() signed_pkgs = DistributionSignedRPM() - rh_signed_pkgs = InstalledRedHatSignedRPM() unsigned_pkgs = InstalledUnsignedRPM() + thirdparty_pkgs = ThirdPartyRPM() for rpm_pkgs in api.consume(InstalledRPM): for pkg in rpm_pkgs.items: if all_signed or is_distro_signed(pkg, distro_keys) or is_exceptional(pkg, rhui_pkgs): signed_pkgs.items.append(pkg) - if distribution == 'rhel': - rh_signed_pkgs.items.append(pkg) - continue - unsigned_pkgs.items.append(pkg) + else: + unsigned_pkgs.items.append(pkg) + thirdparty_pkgs.items.append(pkg) api.produce(signed_pkgs) - api.produce(rh_signed_pkgs) api.produce(unsigned_pkgs) + api.produce(thirdparty_pkgs) diff --git a/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py b/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py index f138bcb2..f55a2295 100644 --- a/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py +++ b/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py @@ -5,13 +5,13 @@ from leapp.libraries.common.config import mock_configs from leapp.models import ( DistributionSignedRPM, fields, - InstalledRedHatSignedRPM, InstalledRPM, InstalledUnsignedRPM, IPUConfig, Model, OSRelease, - RPM + RPM, + ThirdPartyRPM ) RH_PACKAGER = 'Red Hat, Inc. ' @@ -33,11 +33,11 @@ class MockModel(Model): def test_no_installed_rpms(current_actor_context): current_actor_context.run(config_model=mock_configs.CONFIG) assert current_actor_context.consume(DistributionSignedRPM) - assert current_actor_context.consume(InstalledRedHatSignedRPM) assert current_actor_context.consume(InstalledUnsignedRPM) + assert current_actor_context.consume(ThirdPartyRPM) -def test_actor_execution_with_signed_unsigned_data(current_actor_context): +def test_actor_execution_with_signed_and_third_party_pkgs(current_actor_context): installed_rpm = [ RPM(name='sample01', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 199e2f91fd431d51'), @@ -62,13 +62,13 @@ def test_actor_execution_with_signed_unsigned_data(current_actor_context): current_actor_context.run(config_model=mock_configs.CONFIG) assert current_actor_context.consume(DistributionSignedRPM) assert len(current_actor_context.consume(DistributionSignedRPM)[0].items) == 5 - assert current_actor_context.consume(InstalledRedHatSignedRPM) - assert len(current_actor_context.consume(InstalledRedHatSignedRPM)[0].items) == 5 assert current_actor_context.consume(InstalledUnsignedRPM) assert len(current_actor_context.consume(InstalledUnsignedRPM)[0].items) == 4 + assert current_actor_context.consume(ThirdPartyRPM) + assert len(current_actor_context.consume(ThirdPartyRPM)[0].items) == 4 -def test_actor_execution_with_signed_unsigned_data_centos(current_actor_context): +def test_actor_execution_with_signed_and_third_party_pkgs_centos(current_actor_context): CENTOS_PACKAGER = 'CentOS BuildSystem ' config = mock_configs.CONFIG @@ -104,10 +104,41 @@ def test_actor_execution_with_signed_unsigned_data_centos(current_actor_context) current_actor_context.run(config_model=config) assert current_actor_context.consume(DistributionSignedRPM) assert len(current_actor_context.consume(DistributionSignedRPM)[0].items) == 3 - assert current_actor_context.consume(InstalledRedHatSignedRPM) - assert not current_actor_context.consume(InstalledRedHatSignedRPM)[0].items assert current_actor_context.consume(InstalledUnsignedRPM) assert len(current_actor_context.consume(InstalledUnsignedRPM)[0].items) == 6 + assert current_actor_context.consume(ThirdPartyRPM) + assert len(current_actor_context.consume(ThirdPartyRPM)[0].items) == 6 + + +def test_actor_execution_with_signed_unsigned_data_almalinux(current_actor_context): + ALMALINUX_PACKAGER = 'AlmaLinux Packaging Team ' + config = mock_configs.CONFIG + + config.os_release = OSRelease( + release_id='almalinux', + name='AlmaLinux', + pretty_name='AlmaLinux 8.10 (Cerulean Leopard)', + version='8.10 (Cerulean Leopard)', + version_id='8.10' + ) + + installed_rpm = [ + RPM(name='sample01', version='0.1', release='1.sm01', epoch='1', packager=ALMALINUX_PACKAGER, arch='noarch', + pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 2ae81e8aced7258b'), + RPM(name='sample02', version='0.1', release='1.sm01', epoch='1', packager=ALMALINUX_PACKAGER, arch='noarch', + pgpsig='SOME_OTHER_SIG_X'), + RPM(name='sample03', version='0.1', release='1.sm01', epoch='1', packager=ALMALINUX_PACKAGER, arch='noarch', + pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 51d6647ec21ad6ea'), + RPM(name='sample04', version='0.1', release='1.sm01', epoch='1', packager=ALMALINUX_PACKAGER, arch='noarch', + pgpsig='SOME_OTHER_SIG_X'), + ] + + current_actor_context.feed(InstalledRPM(items=installed_rpm)) + current_actor_context.run(config_model=config) + assert current_actor_context.consume(DistributionSignedRPM) + assert len(current_actor_context.consume(DistributionSignedRPM)[0].items) == 2 + assert current_actor_context.consume(InstalledUnsignedRPM) + assert len(current_actor_context.consume(InstalledUnsignedRPM)[0].items) == 2 def test_actor_execution_with_unknown_distro(current_actor_context): @@ -124,8 +155,8 @@ def test_actor_execution_with_unknown_distro(current_actor_context): current_actor_context.feed(InstalledRPM(items=[])) current_actor_context.run(config_model=config) assert not current_actor_context.consume(DistributionSignedRPM) - assert not current_actor_context.consume(InstalledRedHatSignedRPM) assert not current_actor_context.consume(InstalledUnsignedRPM) + assert not current_actor_context.consume(ThirdPartyRPM) def test_all_rpms_signed(current_actor_context): @@ -144,9 +175,8 @@ def test_all_rpms_signed(current_actor_context): current_actor_context.run(config_model=mock_configs.CONFIG_ALL_SIGNED) assert current_actor_context.consume(DistributionSignedRPM) assert len(current_actor_context.consume(DistributionSignedRPM)[0].items) == 4 - assert current_actor_context.consume(InstalledRedHatSignedRPM) - assert len(current_actor_context.consume(InstalledRedHatSignedRPM)[0].items) == 4 assert not current_actor_context.consume(InstalledUnsignedRPM)[0].items + assert not current_actor_context.consume(ThirdPartyRPM)[0].items def test_katello_pkg_goes_to_signed(current_actor_context): @@ -164,9 +194,8 @@ def test_katello_pkg_goes_to_signed(current_actor_context): current_actor_context.run(config_model=mock_configs.CONFIG_ALL_SIGNED) assert current_actor_context.consume(DistributionSignedRPM) assert len(current_actor_context.consume(DistributionSignedRPM)[0].items) == 1 - assert current_actor_context.consume(InstalledRedHatSignedRPM) - assert len(current_actor_context.consume(InstalledRedHatSignedRPM)[0].items) == 1 assert not current_actor_context.consume(InstalledUnsignedRPM)[0].items + assert not current_actor_context.consume(ThirdPartyRPM)[0].items def test_gpg_pubkey_pkg(current_actor_context): @@ -181,10 +210,10 @@ def test_gpg_pubkey_pkg(current_actor_context): current_actor_context.run(config_model=mock_configs.CONFIG) assert current_actor_context.consume(DistributionSignedRPM) assert len(current_actor_context.consume(DistributionSignedRPM)[0].items) == 2 - assert current_actor_context.consume(InstalledRedHatSignedRPM) - assert len(current_actor_context.consume(InstalledRedHatSignedRPM)[0].items) == 2 assert current_actor_context.consume(InstalledUnsignedRPM) assert not current_actor_context.consume(InstalledUnsignedRPM)[0].items + assert current_actor_context.consume(ThirdPartyRPM) + assert not current_actor_context.consume(ThirdPartyRPM)[0].items def test_create_lookup(): @@ -238,7 +267,7 @@ def test_has_package(current_actor_context): current_actor_context.run(config_model=mock_configs.CONFIG) assert rpms.has_package(DistributionSignedRPM, 'sample01', context=current_actor_context) assert not rpms.has_package(DistributionSignedRPM, 'nosuchpackage', context=current_actor_context) - assert rpms.has_package(InstalledRedHatSignedRPM, 'sample01', context=current_actor_context) - assert not rpms.has_package(InstalledRedHatSignedRPM, 'nosuchpackage', context=current_actor_context) assert rpms.has_package(InstalledUnsignedRPM, 'sample02', context=current_actor_context) assert not rpms.has_package(InstalledUnsignedRPM, 'nosuchpackage', context=current_actor_context) + assert rpms.has_package(ThirdPartyRPM, 'sample02', context=current_actor_context) + assert not rpms.has_package(ThirdPartyRPM, 'nosuchpackage', context=current_actor_context) diff --git a/repos/system_upgrade/common/actors/efibootorderfix/finalization/actor.py b/repos/system_upgrade/common/actors/efibootorderfix/finalization/actor.py index f42909f0..6383a56f 100644 --- a/repos/system_upgrade/common/actors/efibootorderfix/finalization/actor.py +++ b/repos/system_upgrade/common/actors/efibootorderfix/finalization/actor.py @@ -1,17 +1,117 @@ +import os +import re + +from leapp.libraries.stdlib import run, api from leapp.actors import Actor -from leapp.libraries.common import efi_reboot_fix +from leapp.models import InstalledTargetKernelVersion, KernelCmdlineArg, FirmwareFacts, MountEntry from leapp.tags import FinalizationPhaseTag, IPUWorkflowTag +from leapp.exceptions import StopActorExecutionError class EfiFinalizationFix(Actor): """ - Adjust EFI boot entry for final reboot + Ensure that EFI boot order is updated, which is particularly necessary + when upgrading to a different OS distro. Also rebuilds grub config + if necessary. """ name = 'efi_finalization_fix' - consumes = () + consumes = (KernelCmdlineArg, InstalledTargetKernelVersion, FirmwareFacts, MountEntry) produces = () - tags = (FinalizationPhaseTag, IPUWorkflowTag) + tags = (FinalizationPhaseTag.Before, IPUWorkflowTag) def process(self): - efi_reboot_fix.maybe_emit_updated_boot_entry() + is_system_efi = False + ff = next(self.consume(FirmwareFacts), None) + + dirname = { + 'AlmaLinux': 'almalinux', + 'CentOS Linux': 'centos', + 'CentOS Stream': 'centos', + 'Oracle Linux Server': 'redhat', + 'Red Hat Enterprise Linux': 'redhat', + 'Rocky Linux': 'rocky', + 'Scientific Linux': 'redhat', + } + + efi_shimname_dict = { + 'x86_64': 'shimx64.efi', + 'aarch64': 'shimaa64.efi' + } + + def devparts(dev): + """ + NVMe block devices aren't named like SCSI/ATA/etc block devices and must be parsed differently. + SCSI/ATA/etc devices have a syntax resembling /dev/sdb4 for the 4th partition on the 2nd disk. + NVMe devices have a syntax resembling /dev/nvme0n2p4 for the 4th partition on the 2nd disk. + """ + if '/dev/nvme' in dev: + """ + NVMe + """ + part = next(re.finditer(r'p\d+$', dev)).group(0) + dev = dev[:-len(part)] + part = part[1:] + else: + """ + Non-NVMe (SCSI, ATA, etc) + """ + part = next(re.finditer(r'\d+$', dev)).group(0) + dev = dev[:-len(part)] + return [dev, part]; + + with open('/etc/system-release', 'r') as sr: + release_line = next(line for line in sr if 'release' in line) + distro = release_line.split(' release ', 1)[0] + + efi_bootentry_label = distro + distro_dir = dirname.get(distro, 'default') + shim_filename = efi_shimname_dict.get(api.current_actor().configuration.architecture, 'shimx64.efi') + + shim_path = '/boot/efi/EFI/' + distro_dir + '/' + shim_filename + grub_cfg_path = '/boot/efi/EFI/' + distro_dir + '/grub.cfg' + bootmgr_path = '\\EFI\\' + distro_dir + '\\' + shim_filename + + has_efibootmgr = os.path.exists('/sbin/efibootmgr') + has_shim = os.path.exists(shim_path) + has_grub_cfg = os.path.exists(grub_cfg_path) + + if not ff: + raise StopActorExecutionError( + 'Could not identify system firmware', + details={'details': 'Actor did not receive FirmwareFacts message.'} + ) + + if not has_efibootmgr: + return + + for fact in self.consume(FirmwareFacts): + if fact.firmware == 'efi': + is_system_efi = True + break + + if is_system_efi and has_shim: + efidevlist = [] + with open('/proc/mounts', 'r') as fp: + for line in fp: + if '/boot/efi' in line: + efidevpath = line.split(' ', 1)[0] + efidevpart = efidevpath.split('/')[-1] + if os.path.exists('/proc/mdstat'): + with open('/proc/mdstat', 'r') as mds: + for line in mds: + if line.startswith(efidevpart): + mddev = line.split(' ') + for md in mddev: + if '[' in md: + efimd = md.split('[', 1)[0] + efidp = efidevpath.replace(efidevpart, efimd) + efidevlist.append(efidp) + if len(efidevlist) == 0: + efidevlist.append(efidevpath) + for devpath in efidevlist: + efidev, efipart = devparts(devpath) + run(['/sbin/efibootmgr', '-c', '-d', efidev, '-p', efipart, '-l', bootmgr_path, '-L', efi_bootentry_label]) + + if not has_grub_cfg: + run(['/sbin/grub2-mkconfig', '-o', grub_cfg_path]) diff --git a/repos/system_upgrade/common/actors/filterrpmtransactionevents/actor.py b/repos/system_upgrade/common/actors/filterrpmtransactionevents/actor.py index 582a5821..18f2c33f 100644 --- a/repos/system_upgrade/common/actors/filterrpmtransactionevents/actor.py +++ b/repos/system_upgrade/common/actors/filterrpmtransactionevents/actor.py @@ -32,6 +32,7 @@ class FilterRpmTransactionTasks(Actor): to_remove = set() to_keep = set() to_upgrade = set() + to_reinstall = set() modules_to_enable = {} modules_to_reset = {} for event in self.consume(RpmTransactionTasks, PESRpmTransactionTasks): @@ -39,13 +40,14 @@ class FilterRpmTransactionTasks(Actor): to_install.update(event.to_install) to_remove.update(installed_pkgs.intersection(event.to_remove)) to_keep.update(installed_pkgs.intersection(event.to_keep)) + to_reinstall.update(installed_pkgs.intersection(event.to_reinstall)) modules_to_enable.update({'{}:{}'.format(m.name, m.stream): m for m in event.modules_to_enable}) modules_to_reset.update({'{}:{}'.format(m.name, m.stream): m for m in event.modules_to_reset}) to_remove.difference_update(to_keep) # run upgrade for the rest of RH signed pkgs which we do not have rule for - to_upgrade = installed_pkgs - (to_install | to_remove) + to_upgrade = installed_pkgs - (to_install | to_remove | to_reinstall) self.produce(FilteredRpmTransactionTasks( local_rpms=list(local_rpms), @@ -53,5 +55,6 @@ class FilterRpmTransactionTasks(Actor): to_remove=list(to_remove), to_keep=list(to_keep), to_upgrade=list(to_upgrade), + to_reinstall=list(to_reinstall), modules_to_reset=list(modules_to_reset.values()), modules_to_enable=list(modules_to_enable.values()))) diff --git a/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py b/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py index 6184121b..8b7faffb 100644 --- a/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py +++ b/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py @@ -129,6 +129,13 @@ def test_construct_models_for_paths_matching_source_major(source_major_version, '9': ['10.0'] } ), + ( + 'almalinux', 'default', + { + '8.10': ['9.0', '9.1', '9.2', '9.3', '9.4', '9.5', '9.6'], + '9.6': ['10.0'] + } + ), ) ) def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flavour, expected_result): @@ -147,6 +154,12 @@ def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flav '9.6': ['10.0'], '9': ['10.0'] } + }, + 'almalinux': { + 'default': { + '8.10': ['9.0', '9.1', '9.2', '9.3', '9.4', '9.5', '9.6'], + '9.6': ['10.0'] + } } } @@ -160,6 +173,7 @@ def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flav [ (('centos', '8', '9'), ('8.10', '9.5')), (('rhel', '8.10', '9.4'), ('8.10', '9.4')), + (('almalinux', '8.10', '9.6'), ('8.10', '9.6')), ] ) def test_virtual_version_construction(construction_params, expected_versions): @@ -186,6 +200,12 @@ def test_virtual_version_construction(construction_params, expected_versions): '9': '9.5', } }, + 'almalinux': { + 'default': { + '8.10': ['9.0', '9.1', '9.2', '9.3', '9.4', '9.5', '9.6'], + '9.6': ['10.0'] + } + }, } result = ipuworkflowconfig.construct_virtual_versions(defined_upgrade_paths, *construction_params) diff --git a/repos/system_upgrade/common/actors/missinggpgkeysinhibitor/libraries/missinggpgkey.py b/repos/system_upgrade/common/actors/missinggpgkeysinhibitor/libraries/missinggpgkey.py index 32e4527b..1e595e9a 100644 --- a/repos/system_upgrade/common/actors/missinggpgkeysinhibitor/libraries/missinggpgkey.py +++ b/repos/system_upgrade/common/actors/missinggpgkeysinhibitor/libraries/missinggpgkey.py @@ -152,11 +152,11 @@ def _report(title, summary, keys, inhibitor=False): ) hint = ( 'Check the path to the listed GPG keys is correct, the keys are valid and' - ' import them into the host RPM DB or store them inside the {} directory' + ' import them into the host RPM DB or store them inside on of the {} directories' ' prior the upgrade.' ' If you want to proceed the in-place upgrade without checking any RPM' ' signatures, execute leapp with the `--nogpgcheck` option.' - .format(get_path_to_gpg_certs()) + .format(','.format(get_path_to_gpg_certs())) ) groups = [reporting.Groups.REPOSITORY] if inhibitor: @@ -188,7 +188,7 @@ def _report_missing_keys(keys): summary = ( 'Some of the target repositories require GPG keys that are not installed' ' in the current RPM DB or are not stored in the {trust_dir} directory.' - .format(trust_dir=get_path_to_gpg_certs()) + .format(trust_dir=','.join(get_path_to_gpg_certs())) ) _report('Detected unknown GPG keys for target system repositories', summary, keys, True) @@ -262,11 +262,12 @@ def _report_repos_missing_keys(repos): def register_dnfworkaround(): - api.produce(DNFWorkaround( - display_name='import trusted gpg keys to RPM DB', - script_path=api.current_actor().get_common_tool_path('importrpmgpgkeys'), - script_args=[get_path_to_gpg_certs()], - )) + for trust_certs_dir in get_path_to_gpg_certs(): + api.produce(DNFWorkaround( + display_name='import trusted gpg keys to RPM DB', + script_path=api.current_actor().get_common_tool_path('importrpmgpgkeys'), + script_args=[trust_certs_dir], + )) @suppress_deprecation(TMPTargetRepositoriesFacts) diff --git a/repos/system_upgrade/common/actors/peseventsscanner/actor.py b/repos/system_upgrade/common/actors/peseventsscanner/actor.py index f801f1a1..cb911471 100644 --- a/repos/system_upgrade/common/actors/peseventsscanner/actor.py +++ b/repos/system_upgrade/common/actors/peseventsscanner/actor.py @@ -10,7 +10,8 @@ from leapp.models import ( RepositoriesMapping, RepositoriesSetupTasks, RHUIInfo, - RpmTransactionTasks + RpmTransactionTasks, + ActiveVendorList, ) from leapp.reporting import Report from leapp.tags import FactsPhaseTag, IPUWorkflowTag @@ -33,6 +34,7 @@ class PesEventsScanner(Actor): RepositoriesMapping, RHUIInfo, RpmTransactionTasks, + ActiveVendorList, ) produces = (ConsumedDataAsset, PESRpmTransactionTasks, RepositoriesSetupTasks, Report) tags = (IPUWorkflowTag, FactsPhaseTag) diff --git a/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_event_parsing.py b/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_event_parsing.py index f24dda68..7ee5d016 100644 --- a/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_event_parsing.py +++ b/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_event_parsing.py @@ -58,6 +58,7 @@ class Action(IntEnum): MERGED = 5 MOVED = 6 RENAMED = 7 + REINSTALLED = 8 def get_pes_events(pes_json_directory, pes_json_filename): @@ -72,13 +73,14 @@ def get_pes_events(pes_json_directory, pes_json_filename): # a case as we have no work to do in such a case here. events_data = fetch.load_data_asset(api.current_actor(), pes_json_filename, + asset_directory=pes_json_directory, asset_fulltext_name='PES events file', docs_url='', docs_title='') if not events_data: return None - if not events_data.get('packageinfo'): + if events_data.get('packageinfo') is None: raise ValueError('Found PES data with invalid structure') all_events = list(chain(*[parse_entry(entry) for entry in events_data['packageinfo']])) diff --git a/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py b/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py index e6741293..7a7e9ebf 100644 --- a/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py +++ b/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py @@ -1,5 +1,6 @@ from collections import defaultdict, namedtuple from functools import partial +import os from leapp import reporting from leapp.exceptions import StopActorExecutionError @@ -7,6 +8,7 @@ from leapp.libraries.actor import peseventsscanner_repomap from leapp.libraries.actor.pes_event_parsing import Action, get_pes_events, Package from leapp.libraries.common import rpms from leapp.libraries.common.config import version +from leapp.libraries.common.repomaputils import combine_repomap_messages from leapp.libraries.stdlib import api from leapp.libraries.stdlib.config import is_verbose from leapp.models import ( @@ -20,7 +22,8 @@ from leapp.models import ( RepositoriesMapping, RepositoriesSetupTasks, RHUIInfo, - RpmTransactionTasks + RpmTransactionTasks, + ActiveVendorList, ) SKIPPED_PKGS_MSG = ( @@ -31,8 +34,9 @@ SKIPPED_PKGS_MSG = ( 'for details.\nThe list of these packages:' ) +VENDORS_DIR = "/etc/leapp/files/vendors.d" -TransactionConfiguration = namedtuple('TransactionConfiguration', ('to_install', 'to_remove', 'to_keep')) +TransactionConfiguration = namedtuple('TransactionConfiguration', ('to_install', 'to_remove', 'to_keep', 'to_reinstall')) def get_cloud_provider_name(cloud_provider_variant): @@ -86,7 +90,7 @@ def get_transaction_configuration(): :return: TransactionConfiguration """ - transaction_configuration = TransactionConfiguration(to_install=set(), to_remove=set(), to_keep=set()) + transaction_configuration = TransactionConfiguration(to_install=set(), to_remove=set(), to_keep=set(), to_reinstall=set()) _Pkg = partial(Package, repository=None, modulestream=None) @@ -94,6 +98,7 @@ def get_transaction_configuration(): transaction_configuration.to_install.update(_Pkg(name=pkg_name) for pkg_name in tasks.to_install) transaction_configuration.to_remove.update(_Pkg(name=pkg_name) for pkg_name in tasks.to_remove) transaction_configuration.to_keep.update(_Pkg(name=pkg_name) for pkg_name in tasks.to_keep) + transaction_configuration.to_reinstall.update(_Pkg(name=pkg_name) for pkg_name in tasks.to_reinstall) return transaction_configuration @@ -133,6 +138,7 @@ def compute_pkg_changes_between_consequent_releases(source_installed_pkgs, logger = api.current_logger() # Start with the installed packages and modify the set according to release events target_pkgs = set(source_installed_pkgs) + pkgs_to_reinstall = set() release_events = [e for e in events if e.to_release == release] @@ -176,9 +182,12 @@ def compute_pkg_changes_between_consequent_releases(source_installed_pkgs, target_pkgs = target_pkgs.difference(event.out_pkgs) target_pkgs = target_pkgs.union(event.out_pkgs) + if (event.action == Action.REINSTALLED and is_any_in_pkg_present): + pkgs_to_reinstall = pkgs_to_reinstall.union(event.in_pkgs) + pkgs_to_demodularize = pkgs_to_demodularize.difference(event.in_pkgs) - return (target_pkgs, pkgs_to_demodularize) + return (target_pkgs, pkgs_to_demodularize, pkgs_to_reinstall) def remove_undesired_events(events, relevant_to_releases): @@ -244,15 +253,17 @@ def compute_packages_on_target_system(source_pkgs, events, releases): did_processing_cross_major_version = True pkgs_to_demodularize = {pkg for pkg in target_pkgs if pkg.modulestream} - target_pkgs, pkgs_to_demodularize = compute_pkg_changes_between_consequent_releases(target_pkgs, events, - release, seen_pkgs, - pkgs_to_demodularize) + target_pkgs, pkgs_to_demodularize, pkgs_to_reinstall = compute_pkg_changes_between_consequent_releases( + target_pkgs, events, + release, seen_pkgs, + pkgs_to_demodularize + ) seen_pkgs = seen_pkgs.union(target_pkgs) demodularized_pkgs = {Package(pkg.name, pkg.repository, None) for pkg in pkgs_to_demodularize} demodularized_target_pkgs = target_pkgs.difference(pkgs_to_demodularize).union(demodularized_pkgs) - return (demodularized_target_pkgs, pkgs_to_demodularize) + return (demodularized_target_pkgs, pkgs_to_demodularize, pkgs_to_reinstall) def compute_rpm_tasks_from_pkg_set_diff(source_pkgs, target_pkgs, pkgs_to_demodularize): @@ -356,15 +367,13 @@ def get_pesid_to_repoid_map(target_pesids): :return: Dictionary mapping the target_pesids to their corresponding repoid """ - repositories_map_msgs = api.consume(RepositoriesMapping) - repositories_map_msg = next(repositories_map_msgs, None) - if list(repositories_map_msgs): - api.current_logger().warning('Unexpectedly received more than one RepositoriesMapping message.') - if not repositories_map_msg: + repositories_map_msgs = list(api.consume(RepositoriesMapping)) + if not repositories_map_msgs: raise StopActorExecutionError( 'Cannot parse RepositoriesMapping data properly', details={'Problem': 'Did not receive a message with mapped repositories'} ) + repositories_map_msg = combine_repomap_messages(repositories_map_msgs) rhui_info = next(api.consume(RHUIInfo), None) cloud_provider = rhui_info.provider if rhui_info else '' @@ -554,6 +563,19 @@ def process(): if not events: return + active_vendors = [] + for vendor_list in api.consume(ActiveVendorList): + active_vendors.extend(vendor_list.data) + + pes_json_suffix = "_pes.json" + if os.path.isdir(VENDORS_DIR): + vendor_pesfiles = list(filter(lambda vfile: pes_json_suffix in vfile, os.listdir(VENDORS_DIR))) + + for pesfile in vendor_pesfiles: + if pesfile[:-len(pes_json_suffix)] in active_vendors: + vendor_events = get_pes_events(VENDORS_DIR, pesfile) + events.extend(vendor_events) + releases = get_relevant_releases(events) installed_pkgs = get_installed_pkgs() transaction_configuration = get_transaction_configuration() @@ -567,7 +589,7 @@ def process(): events = remove_undesired_events(events, releases) # Apply events - compute what packages should the target system have - target_pkgs, pkgs_to_demodularize = compute_packages_on_target_system(pkgs_to_begin_computation_with, + target_pkgs, pkgs_to_demodularize, pkgs_to_reinstall = compute_packages_on_target_system(pkgs_to_begin_computation_with, events, releases) # Packages coming out of the events have PESID as their repository, however, we need real repoid @@ -587,4 +609,5 @@ def process(): rpm_tasks = include_instructions_from_transaction_configuration(rpm_tasks, transaction_configuration, installed_pkgs) if rpm_tasks: + rpm_tasks.to_reinstall = sorted(pkgs_to_reinstall) api.produce(rpm_tasks) diff --git a/repos/system_upgrade/common/actors/redhatsignedrpmcheck/actor.py b/repos/system_upgrade/common/actors/redhatsignedrpmcheck/actor.py deleted file mode 100644 index a3555e52..00000000 --- a/repos/system_upgrade/common/actors/redhatsignedrpmcheck/actor.py +++ /dev/null @@ -1,22 +0,0 @@ -from leapp.actors import Actor -from leapp.libraries.actor.redhatsignedrpmcheck import check_unsigned_packages -from leapp.models import InstalledUnsignedRPM -from leapp.reporting import Report -from leapp.tags import ChecksPhaseTag, IPUWorkflowTag - - -class RedHatSignedRpmCheck(Actor): - """ - Check if there are packages not signed by Red Hat in use. If yes, warn user about it. - - If any any installed RPM package does not contain a valid signature from Red Hat, a message - containing a warning is produced. - """ - - name = 'red_hat_signed_rpm_check' - consumes = (InstalledUnsignedRPM,) - produces = (Report,) - tags = (IPUWorkflowTag, ChecksPhaseTag) - - def process(self): - check_unsigned_packages() diff --git a/repos/system_upgrade/common/actors/redhatsignedrpmcheck/libraries/redhatsignedrpmcheck.py b/repos/system_upgrade/common/actors/redhatsignedrpmcheck/libraries/redhatsignedrpmcheck.py deleted file mode 100644 index 14ade534..00000000 --- a/repos/system_upgrade/common/actors/redhatsignedrpmcheck/libraries/redhatsignedrpmcheck.py +++ /dev/null @@ -1,62 +0,0 @@ -from leapp import reporting -from leapp.libraries.stdlib import api -from leapp.libraries.stdlib.config import is_verbose -from leapp.models import InstalledUnsignedRPM - - -def generate_report(packages): - """ Generate a report if there are unsigned packages installed on the system """ - if not packages: - return - unsigned_packages_new_line = '\n'.join(['- ' + p for p in packages]) - title = 'Packages not signed by Red Hat found on the system' - summary = ('The following packages have not been signed by Red Hat' - ' and may be removed during the upgrade process in case Red Hat-signed' - ' packages to be removed during the upgrade depend on them:\n{}' - .format(unsigned_packages_new_line)) - hint = ( - 'The most simple solution that does not require additional knowledge' - ' about the upgrade process' - ' is the uninstallation of such packages before the upgrade and' - ' installing these (or their newer versions compatible with the target' - ' system) back after the upgrade. Also you can just try to upgrade the' - ' system on a testing machine (or after the full system backup) to see' - ' the result.\n' - 'However, it is common use case to migrate or upgrade installed third' - ' party packages together with the system during the in-place upgrade' - ' process. To examine how to customize the process to deal with such' - ' packages, follow the documentation in the attached link' - ' for more details.' - ) - reporting.create_report([ - reporting.Title(title), - reporting.Summary(summary), - reporting.Severity(reporting.Severity.HIGH), - reporting.Groups([reporting.Groups.SANITY]), - reporting.Remediation(hint=hint), - reporting.ExternalLink( - url='https://red.ht/customize-rhel-upgrade-actors', - title='Handling the migration of your custom and third-party applications' - ) - ]) - - if is_verbose(): - api.show_message(summary) - - -def get_unsigned_packages(): - """ Get list of unsigned packages installed in the system """ - rpm_messages = api.consume(InstalledUnsignedRPM) - data = next(rpm_messages, InstalledUnsignedRPM()) - if list(rpm_messages): - api.current_logger().warning('Unexpectedly received more than one InstalledUnsignedRPM message.') - unsigned_packages = set() - unsigned_packages.update([pkg.name for pkg in data.items]) - unsigned_packages = list(unsigned_packages) - unsigned_packages.sort() - return unsigned_packages - - -def check_unsigned_packages(): - """ Check and generate reports if system contains unsigned installed packages""" - generate_report(get_unsigned_packages()) diff --git a/repos/system_upgrade/common/actors/redhatsignedrpmcheck/tests/test_redhatsignedrpmcheck.py b/repos/system_upgrade/common/actors/redhatsignedrpmcheck/tests/test_redhatsignedrpmcheck.py deleted file mode 100644 index 8ec4c16f..00000000 --- a/repos/system_upgrade/common/actors/redhatsignedrpmcheck/tests/test_redhatsignedrpmcheck.py +++ /dev/null @@ -1,47 +0,0 @@ -from leapp import reporting -from leapp.libraries.actor import redhatsignedrpmcheck -from leapp.libraries.common.testutils import create_report_mocked, produce_mocked -from leapp.libraries.stdlib import api -from leapp.models import InstalledUnsignedRPM, RPM - -RH_PACKAGER = 'Red Hat, Inc. ' - - -def test_actor_execution_without_unsigned_data(monkeypatch): - def consume_unsigned_message_mocked(*models): - installed_rpm = [] - yield InstalledUnsignedRPM(items=installed_rpm) - monkeypatch.setattr(api, "consume", consume_unsigned_message_mocked) - monkeypatch.setattr(api, "produce", produce_mocked()) - monkeypatch.setattr(api, "show_message", lambda x: True) - monkeypatch.setattr(reporting, "create_report", create_report_mocked()) - - packages = redhatsignedrpmcheck.get_unsigned_packages() - assert not packages - redhatsignedrpmcheck.generate_report(packages) - assert reporting.create_report.called == 0 - - -def test_actor_execution_with_unsigned_data(monkeypatch): - def consume_unsigned_message_mocked(*models): - installed_rpm = [ - RPM(name='sample02', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch', - pgpsig='SOME_OTHER_SIG_X'), - RPM(name='sample04', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch', - pgpsig='SOME_OTHER_SIG_X'), - RPM(name='sample06', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch', - pgpsig='SOME_OTHER_SIG_X'), - RPM(name='sample08', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch', - pgpsig='SOME_OTHER_SIG_X')] - yield InstalledUnsignedRPM(items=installed_rpm) - - monkeypatch.setattr(api, "consume", consume_unsigned_message_mocked) - monkeypatch.setattr(api, "produce", produce_mocked()) - monkeypatch.setattr(api, "show_message", lambda x: True) - monkeypatch.setattr(reporting, "create_report", create_report_mocked()) - - packages = redhatsignedrpmcheck.get_unsigned_packages() - assert len(packages) == 4 - redhatsignedrpmcheck.generate_report(packages) - assert reporting.create_report.called == 1 - assert 'Packages not signed by Red Hat found' in reporting.create_report.report_fields['title'] diff --git a/repos/system_upgrade/common/actors/reportsettargetrelease/libraries/reportsettargetrelease.py b/repos/system_upgrade/common/actors/reportsettargetrelease/libraries/reportsettargetrelease.py index 3dcf5d95..37f60179 100644 --- a/repos/system_upgrade/common/actors/reportsettargetrelease/libraries/reportsettargetrelease.py +++ b/repos/system_upgrade/common/actors/reportsettargetrelease/libraries/reportsettargetrelease.py @@ -1,5 +1,6 @@ from leapp import reporting from leapp.libraries.common import rhsm +from leapp.libraries.common.config import get_distro_id from leapp.libraries.stdlib import api @@ -49,6 +50,7 @@ def _report_unhandled_release(): def process(): if rhsm.skip_rhsm(): - _report_unhandled_release() + if get_distro_id() == 'rhel': + _report_unhandled_release() else: _report_set_release() diff --git a/repos/system_upgrade/common/actors/reportsettargetrelease/tests/test_targetreleasereport_reportsettargetrelease.py b/repos/system_upgrade/common/actors/reportsettargetrelease/tests/test_targetreleasereport_reportsettargetrelease.py index d8665645..37300c46 100644 --- a/repos/system_upgrade/common/actors/reportsettargetrelease/tests/test_targetreleasereport_reportsettargetrelease.py +++ b/repos/system_upgrade/common/actors/reportsettargetrelease/tests/test_targetreleasereport_reportsettargetrelease.py @@ -26,3 +26,13 @@ def test_report_unhandled_release(monkeypatch): reportsettargetrelease.process() assert reporting.create_report.called == 1 assert 'is going to be kept' in reporting.create_report.report_fields['title'] + + +def test_no_report_on_non_rhel(monkeypatch): + monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(release_id='centos')) + monkeypatch.setattr(rhsm, 'skip_rhsm', lambda: True) # this is always the case on nonrhel + monkeypatch.setattr(reporting, 'create_report', create_report_mocked()) + + reportsettargetrelease.process() + + assert reporting.create_report.called == 0 diff --git a/repos/system_upgrade/common/actors/repositoriesmapping/libraries/repositoriesmapping.py b/repos/system_upgrade/common/actors/repositoriesmapping/libraries/repositoriesmapping.py index d4a64793..4ec1d6e0 100644 --- a/repos/system_upgrade/common/actors/repositoriesmapping/libraries/repositoriesmapping.py +++ b/repos/system_upgrade/common/actors/repositoriesmapping/libraries/repositoriesmapping.py @@ -3,6 +3,7 @@ from collections import defaultdict from leapp.exceptions import StopActorExecutionError from leapp.libraries.common.config.version import get_source_major_version, get_target_major_version +from leapp.libraries.common.repomaputils import RepoMapData from leapp.libraries.common.fetch import load_data_asset from leapp.libraries.common.rpms import get_leapp_packages, LeappComponents from leapp.libraries.stdlib import api @@ -16,121 +17,6 @@ REPOMAP_FILE = 'repomap.json' """The name of the new repository mapping file.""" -class RepoMapData(object): - VERSION_FORMAT = '1.3.0' - - def __init__(self): - self.repositories = [] - self.mapping = {} - - def add_repository(self, data, pesid): - """ - Add new PESIDRepositoryEntry with given pesid from the provided dictionary. - - :param data: A dict containing the data of the added repository. The dictionary structure corresponds - to the repositories entries in the repository mapping JSON schema. - :type data: Dict[str, str] - :param pesid: PES id of the repository family that the newly added repository belongs to. - :type pesid: str - """ - self.repositories.append(PESIDRepositoryEntry( - repoid=data['repoid'], - channel=data['channel'], - rhui=data.get('rhui', ''), - repo_type=data['repo_type'], - arch=data['arch'], - major_version=data['major_version'], - pesid=pesid, - distro=data['distro'], - )) - - def get_repositories(self, valid_major_versions): - """ - Return the list of PESIDRepositoryEntry object matching the specified major versions. - """ - return [repo for repo in self.repositories if repo.major_version in valid_major_versions] - - def add_mapping(self, source_major_version, target_major_version, source_pesid, target_pesid): - """ - Add a new mapping entry that is mapping the source pesid to the destination pesid(s), - relevant in an IPU from the supplied source major version to the supplied target - major version. - - :param str source_major_version: Specifies the major version of the source system - for which the added mapping applies. - :param str target_major_version: Specifies the major version of the target system - for which the added mapping applies. - :param str source_pesid: PESID of the source repository. - :param Union[str|List[str]] target_pesid: A single target PESID or a list of target - PESIDs of the added mapping. - """ - # NOTE: it could be more simple, but I prefer to be sure the input data - # contains just one map per source PESID. - key = '{}:{}'.format(source_major_version, target_major_version) - rmap = self.mapping.get(key, defaultdict(set)) - self.mapping[key] = rmap - if isinstance(target_pesid, list): - rmap[source_pesid].update(target_pesid) - else: - rmap[source_pesid].add(target_pesid) - - def get_mappings(self, src_major_version, dst_major_version): - """ - Return the list of RepoMapEntry objects for the specified upgrade path. - - IOW, the whole mapping for specified IPU. - """ - key = '{}:{}'.format(src_major_version, dst_major_version) - rmap = self.mapping.get(key, None) - if not rmap: - return None - map_list = [] - for src_pesid in sorted(rmap.keys()): - map_list.append(RepoMapEntry(source=src_pesid, target=sorted(rmap[src_pesid]))) - return map_list - - @staticmethod - def load_from_dict(data): - if data['version_format'] != RepoMapData.VERSION_FORMAT: - raise ValueError( - 'The obtained repomap data has unsupported version of format.' - ' Get {} required {}' - .format(data['version_format'], RepoMapData.VERSION_FORMAT) - ) - - repomap = RepoMapData() - - # Load reposiories - existing_pesids = set() - for repo_family in data['repositories']: - existing_pesids.add(repo_family['pesid']) - for repo in repo_family['entries']: - repomap.add_repository(repo, repo_family['pesid']) - - # Load mappings - for mapping in data['mapping']: - for entry in mapping['entries']: - if not isinstance(entry['target'], list): - raise ValueError( - 'The target field of a mapping entry is not a list: {}' - .format(entry) - ) - - for pesid in [entry['source']] + entry['target']: - if pesid not in existing_pesids: - raise ValueError( - 'The {} pesid is not related to any repository.' - .format(pesid) - ) - repomap.add_mapping( - source_major_version=mapping['source_major_version'], - target_major_version=mapping['target_major_version'], - source_pesid=entry['source'], - target_pesid=entry['target'], - ) - return repomap - - def _inhibit_upgrade(msg): local_path = os.path.join('/etc/leapp/file', REPOMAP_FILE) hint = ( diff --git a/repos/system_upgrade/common/actors/repositoriesmapping/tests/files/repomap_example.json b/repos/system_upgrade/common/actors/repositoriesmapping/tests/files/repomap_example.json index 1f04d72d..9ce8c410 100644 --- a/repos/system_upgrade/common/actors/repositoriesmapping/tests/files/repomap_example.json +++ b/repos/system_upgrade/common/actors/repositoriesmapping/tests/files/repomap_example.json @@ -120,6 +120,45 @@ "distro": "centos" } ] + }, + { + "pesid": "pesid8", + "entries": [ + { + "major_version": "8", + "repoid": "some-almalinux-8-repoid1", + "arch": "x86_64", + "repo_type": "rpm", + "channel": "ga", + "distro": "almalinux" + } + ] + }, + { + "pesid": "pesid9", + "entries": [ + { + "major_version": "9", + "repoid": "some-almalinux-9-repoid1", + "arch": "x86_64", + "repo_type": "rpm", + "channel": "ga", + "distro": "almalinux" + } + ] + }, + { + "pesid": "pesid10", + "entries": [ + { + "major_version": "10", + "repoid": "some-almalinux-10-repoid1", + "arch": "x86_64", + "repo_type": "rpm", + "channel": "ga", + "distro": "almalinux" + } + ] } ] } diff --git a/repos/system_upgrade/common/actors/repositoriesmapping/tests/unit_test_repositoriesmapping.py b/repos/system_upgrade/common/actors/repositoriesmapping/tests/unit_test_repositoriesmapping.py index 9d781125..6d1a173a 100644 --- a/repos/system_upgrade/common/actors/repositoriesmapping/tests/unit_test_repositoriesmapping.py +++ b/repos/system_upgrade/common/actors/repositoriesmapping/tests/unit_test_repositoriesmapping.py @@ -52,7 +52,7 @@ def test_scan_existing_valid_data(monkeypatch, adjust_cwd): # 2. Verify that only repositories valid for the current IPU are produced pesid_repos = repo_mapping.repositories fail_description = 'Actor produced incorrect number of IPU-relevant pesid repos.' - assert len(pesid_repos) == 5, fail_description + assert len(pesid_repos) == 6, fail_description expected_pesid_repos = [ PESIDRepositoryEntry( @@ -105,6 +105,16 @@ def test_scan_existing_valid_data(monkeypatch, adjust_cwd): rhui='', distro='centos', ), + PESIDRepositoryEntry( + pesid='pesid8', + major_version='8', + repoid='some-almalinux-8-repoid1', + arch='x86_64', + repo_type='rpm', + channel='ga', + rhui='', + distro='almalinux', + ), ] fail_description = 'Expected pesid repo is not present in the deserialization output.' diff --git a/repos/system_upgrade/common/actors/rpmtransactionconfigtaskscollector/libraries/rpmtransactionconfigtaskscollector.py b/repos/system_upgrade/common/actors/rpmtransactionconfigtaskscollector/libraries/rpmtransactionconfigtaskscollector.py index 43ac1fc4..62aefaf4 100644 --- a/repos/system_upgrade/common/actors/rpmtransactionconfigtaskscollector/libraries/rpmtransactionconfigtaskscollector.py +++ b/repos/system_upgrade/common/actors/rpmtransactionconfigtaskscollector/libraries/rpmtransactionconfigtaskscollector.py @@ -18,21 +18,37 @@ def load_tasks_file(path, logger): return [] +def filter_out(installed_rpm_names, to_filter, debug_msg): + # These are the packages that aren't installed on the system. + filtered_ok = [pkg for pkg in to_filter if pkg not in installed_rpm_names] + + # And these ones are the ones that are. + filtered_out = list(set(to_filter) - set(filtered_ok)) + if filtered_out: + api.current_logger().debug( + debug_msg + + '\n- ' + '\n- '.join(filtered_out) + ) + # We may want to use either of the two sets. + return filtered_ok, filtered_out + + def load_tasks(base_dir, logger): # Loads configuration files to_install, to_keep, and to_remove from the given base directory rpms = next(api.consume(DistributionSignedRPM)) rpm_names = [rpm.name for rpm in rpms.items] + to_install = load_tasks_file(os.path.join(base_dir, 'to_install'), logger) + install_debug_msg = 'The following packages from "to_install" file will be ignored as they are already installed:' # we do not want to put into rpm transaction what is already installed (it will go to "to_upgrade" bucket) - to_install_filtered = [pkg for pkg in to_install if pkg not in rpm_names] + to_install_filtered, _ = filter_out(rpm_names, to_install, install_debug_msg) - filtered = set(to_install) - set(to_install_filtered) - if filtered: - api.current_logger().debug( - 'The following packages from "to_install" file will be ignored as they are already installed:' - '\n- ' + '\n- '.join(filtered)) + to_reinstall = load_tasks_file(os.path.join(base_dir, 'to_reinstall'), logger) + reinstall_debug_msg = 'The following packages from "to_reinstall" file will be ignored as they are not installed:' + _, to_reinstall_filtered = filter_out(rpm_names, to_reinstall, reinstall_debug_msg) return RpmTransactionTasks( to_install=to_install_filtered, + to_reinstall=to_reinstall_filtered, to_keep=load_tasks_file(os.path.join(base_dir, 'to_keep'), logger), to_remove=load_tasks_file(os.path.join(base_dir, 'to_remove'), logger)) diff --git a/repos/system_upgrade/common/actors/scan_default_initramfs/actor.py b/repos/system_upgrade/common/actors/scan_default_initramfs/actor.py new file mode 100644 index 00000000..f0713c48 --- /dev/null +++ b/repos/system_upgrade/common/actors/scan_default_initramfs/actor.py @@ -0,0 +1,20 @@ +from leapp.actors import Actor +from leapp.libraries.actor import scan_default_initramfs as scan_default_initramfs_lib +from leapp.models import DefaultInitramfsInfo, DefaultSourceBootEntry +from leapp.tags import FactsPhaseTag, IPUWorkflowTag + + +class ScanDefaultInitramfs(Actor): + """ + Scan details of the default boot entry's initramfs image. + + Information such as used dracut modules are collected. + """ + + name = 'scan_default_initramfs' + consumes = (DefaultSourceBootEntry,) + produces = (DefaultInitramfsInfo,) + tags = (IPUWorkflowTag, FactsPhaseTag) + + def process(self): + scan_default_initramfs_lib.scan_default_initramfs() diff --git a/repos/system_upgrade/common/actors/scan_default_initramfs/libraries/scan_default_initramfs.py b/repos/system_upgrade/common/actors/scan_default_initramfs/libraries/scan_default_initramfs.py new file mode 100644 index 00000000..8c205bbe --- /dev/null +++ b/repos/system_upgrade/common/actors/scan_default_initramfs/libraries/scan_default_initramfs.py @@ -0,0 +1,41 @@ +from leapp.exceptions import StopActorExecutionError +from leapp.libraries.stdlib import api, CalledProcessError, run +from leapp.models import DefaultInitramfsInfo, DefaultSourceBootEntry + + +def scan_default_initramfs(): + default_boot_entry = next(api.consume(DefaultSourceBootEntry), None) + if not default_boot_entry: + raise StopActorExecutionError('Actor did not receive default boot entry info.') + + target_initramfs_path = default_boot_entry.initramfs_path + try: + initramfs_info = run(['lsinitrd', '-m', target_initramfs_path], split=True)['stdout'] + + except CalledProcessError as err: + details = {'details': str(err)} + msg = 'Failed to list details (lsinitrd) of the default boot entry\'s initramfs.' + raise StopActorExecutionError(msg, details=details) + + dracut_modules_lines = iter(initramfs_info) + + for line in dracut_modules_lines: # Consume everything until `dracut-modules:` is seen + line = line.strip() + if line == 'dracut modules:': + break + + dracut_modules = [] + for module_line in dracut_modules_lines: + module_line = module_line.strip() + if module_line.startswith('========'): + break + + dracut_modules.append(module_line) + + api.current_logger().debug(('Default boot entry\'s initramfs ({}) has ' + 'the following dracut modules: {}').format(default_boot_entry.initramfs_path, + dracut_modules)) + + default_initramfs_info_msg = DefaultInitramfsInfo(path=default_boot_entry.initramfs_path, + used_dracut_modules=dracut_modules) + api.produce(default_initramfs_info_msg) diff --git a/repos/system_upgrade/common/actors/scan_default_initramfs/tests/test_scan_default_initramfs.py b/repos/system_upgrade/common/actors/scan_default_initramfs/tests/test_scan_default_initramfs.py new file mode 100644 index 00000000..f4b4431c --- /dev/null +++ b/repos/system_upgrade/common/actors/scan_default_initramfs/tests/test_scan_default_initramfs.py @@ -0,0 +1,82 @@ +import pytest + +from leapp.exceptions import StopActorExecutionError +from leapp.libraries.actor import scan_default_initramfs +from leapp.libraries.common import testutils +from leapp.libraries.stdlib import CalledProcessError +from leapp.models import DefaultInitramfsInfo, DefaultSourceBootEntry + + +def test_scan_default_initramfs(monkeypatch): + lsinitrd_output = [ + 'Image: /boot/initramfs-5.14.0-570.12.1.el9_6.x86_64.img: 38M', + '========================================================================', + 'Early CPIO image', + '========================================================================', + 'drwxr-xr-x 3 root root 0 Mar 11 04:02 .', + '-rw-r--r-- 1 root root 2 Mar 11 04:02 early_cpio', + 'drwxr-xr-x 3 root root 0 Mar 11 04:02 kernel', + 'drwxr-xr-x 3 root root 0 Mar 11 04:02 kernel/x86', + 'drwxr-xr-x 2 root root 0 Mar 11 04:02 kernel/x86/microcode', + '-rw-r--r-- 1 root root 220160 Mar 11 04:02 kernel/x86/microcode/GenuineIntel.bin', + '========================================================================', + 'Version: dracut-057-87.git20250311.el9_6', + '', + 'dracut modules:', + 'bash', + 'systemd', + '========================================', + ] + + def run_mock(command, split=False): + if command == ['lsinitrd', '-m', '/boot/initramfs-upgrade.x86_64.img']: + return {'stdout': lsinitrd_output} + assert False, f'Unexpected command: {command}' + + default_source_entry_msg = DefaultSourceBootEntry( + kernel_path='/boot/vmlinuz-upgrade.x86_64', + initramfs_path='/boot/initramfs-upgrade.x86_64.img' + ) + + actor_mock = testutils.CurrentActorMocked(msgs=[default_source_entry_msg]) + produce_mock = testutils.produce_mocked() + + monkeypatch.setattr(scan_default_initramfs.api, 'current_actor', actor_mock) + monkeypatch.setattr(scan_default_initramfs.api, 'produce', produce_mock) + monkeypatch.setattr(scan_default_initramfs, 'run', run_mock) + + scan_default_initramfs.scan_default_initramfs() + + assert produce_mock.called + assert len(produce_mock.model_instances) == 1 + assert isinstance(produce_mock.model_instances[0], DefaultInitramfsInfo) + + initramfs_info = produce_mock.model_instances[0] + assert initramfs_info.used_dracut_modules == ['bash', 'systemd'] + + +def test_no_default_boot_entry(monkeypatch): + monkeypatch.setattr(scan_default_initramfs.api, 'current_actor', testutils.CurrentActorMocked(msgs=[])) + + with pytest.raises(StopActorExecutionError): + scan_default_initramfs.scan_default_initramfs() + + +def test_lsinitrd_error(monkeypatch): + default_boot_entry = DefaultSourceBootEntry( + kernel_path='/boot/vmlinuz-upgrade.x86_64', + initramfs_path='/boot/initramfs-upgrade.x86_64.img' + ) + + def run_mock(command, split=False): + if command == ['lsinitrd', '-m', '/boot/initramfs-upgrade.x86_64.img']: + raise CalledProcessError('Simulated lsinitrd call error (in tests)', command, 1) + assert False, f'Unexpected command: {command}' + + actor_mock = testutils.CurrentActorMocked(msgs=[default_boot_entry]) + monkeypatch.setattr(scan_default_initramfs.api, 'current_actor', actor_mock) + monkeypatch.setattr(scan_default_initramfs.api, 'produce', testutils.produce_mocked()) + monkeypatch.setattr(scan_default_initramfs, 'run', run_mock) + + with pytest.raises(StopActorExecutionError): + scan_default_initramfs.scan_default_initramfs() diff --git a/repos/system_upgrade/common/actors/scan_source_boot_loader/actor.py b/repos/system_upgrade/common/actors/scan_source_boot_loader/actor.py new file mode 100644 index 00000000..d38c903b --- /dev/null +++ b/repos/system_upgrade/common/actors/scan_source_boot_loader/actor.py @@ -0,0 +1,18 @@ +from leapp.actors import Actor +from leapp.libraries.actor import scan_source_boot_entry as scan_source_boot_entry_lib +from leapp.models import DefaultSourceBootEntry +from leapp.tags import FactsPhaseTag, IPUWorkflowTag + + +class ScanSourceBootEntry(Actor): + """ + Scan the default boot entry of the source system. + """ + + name = 'scan_source_boot_entry' + consumes = () + produces = (DefaultSourceBootEntry,) + tags = (IPUWorkflowTag, FactsPhaseTag) + + def process(self): + scan_source_boot_entry_lib.scan_default_source_boot_entry() diff --git a/repos/system_upgrade/common/actors/scan_source_boot_loader/libraries/scan_source_boot_entry.py b/repos/system_upgrade/common/actors/scan_source_boot_loader/libraries/scan_source_boot_entry.py new file mode 100644 index 00000000..e25cb251 --- /dev/null +++ b/repos/system_upgrade/common/actors/scan_source_boot_loader/libraries/scan_source_boot_entry.py @@ -0,0 +1,55 @@ +import os + +from leapp.exceptions import StopActorExecutionError +from leapp.libraries.stdlib import api, CalledProcessError, run +from leapp.models import DefaultSourceBootEntry + + +def extract_path_with_img_extension(initramfs_path): + try: + img_extension_start = initramfs_path.rindex('.img') # .index() returns the starting position + initramfs_path = initramfs_path[:img_extension_start + len('.img')] + + if not os.path.exists(initramfs_path): + msg = 'Failed to extract the path to the default\'s boot entry initramfs.' + details = {'details': f'The current initramfs path {initramfs_path}'} + raise StopActorExecutionError(msg, details=details) + + except ValueError: + details = {'details': f'The current initramfs path {initramfs_path}'} + # The system is using some non-traditional naming scheme, no point in trying to extract image path + # Better safe, than sorry, we stop the upgrade here rather than crashing because of a weird path + msg = ('The initrd path of the default kernel does not contain the `.img` extension, ' + 'thus the upgrade cannot safely continue.') + raise StopActorExecutionError(msg, details=details) + return initramfs_path + + +def scan_default_source_boot_entry(): + try: + default_kernel = run(['grubby', '--default-kernel'])['stdout'].strip() + default_kernel_info_lines = run(['grubby', '--info', default_kernel], split=True)['stdout'] + + except CalledProcessError as err: + details = {'details': str(err)} + raise StopActorExecutionError('Failed to determine default boot entry.', details=details) + + # Note that there can be multiple entries listed sharing the same default kernel. + # The parsing is done in a way that it should not fail in such a case. For the current use + # it does not matter -- at the moment we care primarily about the initramfs path, and these + # entries should typically share the initramfs. + + default_kernel_info = {} + for line in default_kernel_info_lines: + key, value = line.split('=', 1) + default_kernel_info[key] = value.strip('"') + + initramfs_path = default_kernel_info['initrd'] + initramfs_path = extract_path_with_img_extension(initramfs_path) + + default_boot_entry_message = DefaultSourceBootEntry( + initramfs_path=initramfs_path, + kernel_path=default_kernel_info['kernel'], + ) + + api.produce(default_boot_entry_message) diff --git a/repos/system_upgrade/common/actors/scan_source_boot_loader/tests/test_scan_source_boot_entry.py b/repos/system_upgrade/common/actors/scan_source_boot_loader/tests/test_scan_source_boot_entry.py new file mode 100644 index 00000000..b6b9e473 --- /dev/null +++ b/repos/system_upgrade/common/actors/scan_source_boot_loader/tests/test_scan_source_boot_entry.py @@ -0,0 +1,61 @@ +import os + +import pytest + +from leapp.exceptions import StopActorExecutionError +from leapp.libraries.actor import scan_source_boot_entry +from leapp.libraries.common import testutils +from leapp.libraries.stdlib import CalledProcessError +from leapp.models import DefaultSourceBootEntry + + +def test_scan_default_source_boot_entry(monkeypatch): + grubby_default_kernel_output = '/boot/vmlinuz-upgrade.x86_64\n' + grubby_default_kernel_info_lines = [ + 'index=3', + 'kernel="/boot/vmlinuz-upgrade.x86_64"', + 'args="ro console=tty0 console=ttyS0,115200 rd_NO_PLYMOUTH"', + 'root="/dev/mapper/rhel_ibm--p8--kvm--03--guest--02-root"', + 'initrd="/boot/initramfs-upgrade.x86_64.img $tuned_initrd"', + 'title="RHEL-Upgrade-Initramfs"', + 'id="f6f57ac447784f60ba924dfbd5776a1b-upgrade.x86_64"', + ] + + def run_mock(command, split=False): + if command == ['grubby', '--default-kernel']: + return {'stdout': grubby_default_kernel_output} + if command == ['grubby', '--info', grubby_default_kernel_output.strip()]: + return {'stdout': grubby_default_kernel_info_lines} + assert False, f'Unexpected command: {command}' + + def exists_mock(path): + if path == '/boot/initramfs-upgrade.x86_64.img': + return True + return os.path.exists(path) + + produce_mock = testutils.produce_mocked() + monkeypatch.setattr(scan_source_boot_entry, 'run', run_mock) + monkeypatch.setattr(scan_source_boot_entry.api, 'produce', produce_mock) + monkeypatch.setattr(scan_source_boot_entry.os.path, 'exists', exists_mock) + + scan_source_boot_entry.scan_default_source_boot_entry() + + assert produce_mock.called + assert len(produce_mock.model_instances) == 1 + assert isinstance(produce_mock.model_instances[0], DefaultSourceBootEntry) + + boot_entry_info = produce_mock.model_instances[0] + assert boot_entry_info.initramfs_path == '/boot/initramfs-upgrade.x86_64.img' + assert boot_entry_info.kernel_path == '/boot/vmlinuz-upgrade.x86_64' + + +def test_error_during_grubby_call(monkeypatch): + def run_mock(command, split=False): + if command == ['grubby', '--default-kernel']: + raise CalledProcessError('Simulated grubby call error (in tests)', command, 1) + assert False, f'Unexpected command: {command}' + + monkeypatch.setattr(scan_source_boot_entry, 'run', run_mock) + + with pytest.raises(StopActorExecutionError): + scan_source_boot_entry.scan_default_source_boot_entry() diff --git a/repos/system_upgrade/common/actors/scanvendorrepofiles/actor.py b/repos/system_upgrade/common/actors/scanvendorrepofiles/actor.py new file mode 100644 index 00000000..a5e481cb --- /dev/null +++ b/repos/system_upgrade/common/actors/scanvendorrepofiles/actor.py @@ -0,0 +1,26 @@ +from leapp.actors import Actor +from leapp.libraries.actor import scanvendorrepofiles +from leapp.models import ( + CustomTargetRepositoryFile, + ActiveVendorList, + VendorCustomTargetRepositoryList, +) +from leapp.tags import FactsPhaseTag, IPUWorkflowTag + + +class ScanVendorRepofiles(Actor): + """ + Load and produce custom repository data from vendor-provided files. + Only those vendors whose source system repoids were found on the system will be included. + """ + + name = "scan_vendor_repofiles" + consumes = ActiveVendorList + produces = ( + CustomTargetRepositoryFile, + VendorCustomTargetRepositoryList, + ) + tags = (FactsPhaseTag, IPUWorkflowTag) + + def process(self): + scanvendorrepofiles.process() diff --git a/repos/system_upgrade/common/actors/scanvendorrepofiles/libraries/scanvendorrepofiles.py b/repos/system_upgrade/common/actors/scanvendorrepofiles/libraries/scanvendorrepofiles.py new file mode 100644 index 00000000..84392101 --- /dev/null +++ b/repos/system_upgrade/common/actors/scanvendorrepofiles/libraries/scanvendorrepofiles.py @@ -0,0 +1,72 @@ +import os + +from leapp.libraries.common import repofileutils +from leapp.libraries.stdlib import api +from leapp.models import ( + CustomTargetRepository, + CustomTargetRepositoryFile, + ActiveVendorList, + VendorCustomTargetRepositoryList, +) + + +VENDORS_DIR = "/etc/leapp/files/vendors.d/" +REPOFILE_SUFFIX = ".repo" + + +def process(): + """ + Produce CustomTargetRepository msgs for the vendor repo files inside the + . + + The CustomTargetRepository messages are produced only if a "from" vendor repository + listed indide its map matched one of the repositories active on the system. + """ + if not os.path.isdir(VENDORS_DIR): + api.current_logger().debug( + "The {} directory doesn't exist. Nothing to do.".format(VENDORS_DIR) + ) + return + + for repofile_name in os.listdir(VENDORS_DIR): + if not repofile_name.endswith(REPOFILE_SUFFIX): + continue + # Cut the .repo part to get only the name. + vendor_name = repofile_name[:-5] + + active_vendors = [] + for vendor_list in api.consume(ActiveVendorList): + active_vendors.extend(vendor_list.data) + + api.current_logger().debug("Active vendor list: {}".format(active_vendors)) + + if vendor_name not in active_vendors: + api.current_logger().debug( + "Vendor {} not in active list, skipping".format(vendor_name) + ) + continue + + full_repo_path = os.path.join(VENDORS_DIR, repofile_name) + parsed_repofile = repofileutils.parse_repofile(full_repo_path) + api.current_logger().debug( + "Vendor {} found in active list, processing file {}".format(vendor_name, repofile_name) + ) + + api.produce(CustomTargetRepositoryFile(file=full_repo_path)) + + custom_vendor_repos = [ + CustomTargetRepository( + repoid=repo.repoid, + name=repo.name, + baseurl=repo.baseurl, + enabled=repo.enabled, + ) for repo in parsed_repofile.data + ] + + api.produce( + VendorCustomTargetRepositoryList(vendor=vendor_name, repos=custom_vendor_repos) + ) + + api.current_logger().info( + "The {} directory exists, vendor repositories loaded.".format(VENDORS_DIR) + ) diff --git a/repos/system_upgrade/common/actors/scanvendorrepofiles/tests/test_scanvendorrepofiles.py b/repos/system_upgrade/common/actors/scanvendorrepofiles/tests/test_scanvendorrepofiles.py new file mode 100644 index 00000000..cb5c7ab7 --- /dev/null +++ b/repos/system_upgrade/common/actors/scanvendorrepofiles/tests/test_scanvendorrepofiles.py @@ -0,0 +1,131 @@ +import os + +from leapp.libraries.actor import scancustomrepofile +from leapp.libraries.common import repofileutils +from leapp.libraries.common.testutils import produce_mocked +from leapp.libraries.stdlib import api + +from leapp.models import (CustomTargetRepository, CustomTargetRepositoryFile, + RepositoryData, RepositoryFile) + + +_REPODATA = [ + RepositoryData(repoid="repo1", name="repo1name", baseurl="repo1url", enabled=True), + RepositoryData(repoid="repo2", name="repo2name", baseurl="repo2url", enabled=False), + RepositoryData(repoid="repo3", name="repo3name", enabled=True), + RepositoryData(repoid="repo4", name="repo4name", mirrorlist="mirror4list", enabled=True), +] + +_CUSTOM_REPOS = [ + CustomTargetRepository(repoid="repo1", name="repo1name", baseurl="repo1url", enabled=True), + CustomTargetRepository(repoid="repo2", name="repo2name", baseurl="repo2url", enabled=False), + CustomTargetRepository(repoid="repo3", name="repo3name", baseurl=None, enabled=True), + CustomTargetRepository(repoid="repo4", name="repo4name", baseurl=None, enabled=True), +] + +_CUSTOM_REPO_FILE_MSG = CustomTargetRepositoryFile(file=scancustomrepofile.CUSTOM_REPO_PATH) + + +_TESTING_REPODATA = [ + RepositoryData(repoid="repo1-stable", name="repo1name", baseurl="repo1url", enabled=True), + RepositoryData(repoid="repo2-testing", name="repo2name", baseurl="repo2url", enabled=False), + RepositoryData(repoid="repo3-stable", name="repo3name", enabled=False), + RepositoryData(repoid="repo4-testing", name="repo4name", mirrorlist="mirror4list", enabled=True), +] + +_TESTING_CUSTOM_REPOS_STABLE_TARGET = [ + CustomTargetRepository(repoid="repo1-stable", name="repo1name", baseurl="repo1url", enabled=True), + CustomTargetRepository(repoid="repo2-testing", name="repo2name", baseurl="repo2url", enabled=False), + CustomTargetRepository(repoid="repo3-stable", name="repo3name", baseurl=None, enabled=False), + CustomTargetRepository(repoid="repo4-testing", name="repo4name", baseurl=None, enabled=True), +] + +_TESTING_CUSTOM_REPOS_BETA_TARGET = [ + CustomTargetRepository(repoid="repo1-stable", name="repo1name", baseurl="repo1url", enabled=True), + CustomTargetRepository(repoid="repo2-testing", name="repo2name", baseurl="repo2url", enabled=True), + CustomTargetRepository(repoid="repo3-stable", name="repo3name", baseurl=None, enabled=False), + CustomTargetRepository(repoid="repo4-testing", name="repo4name", baseurl=None, enabled=True), +] + +_PROCESS_STABLE_TARGET = "stable" +_PROCESS_BETA_TARGET = "beta" + + +class LoggerMocked(object): + def __init__(self): + self.infomsg = None + self.debugmsg = None + + def info(self, msg): + self.infomsg = msg + + def debug(self, msg): + self.debugmsg = msg + + def __call__(self): + return self + + +def test_no_repofile(monkeypatch): + monkeypatch.setattr(os.path, 'isfile', lambda dummy: False) + monkeypatch.setattr(api, 'produce', produce_mocked()) + monkeypatch.setattr(api, 'current_logger', LoggerMocked()) + scancustomrepofile.process() + msg = "The {} file doesn't exist. Nothing to do.".format(scancustomrepofile.CUSTOM_REPO_PATH) + assert api.current_logger.debugmsg == msg + assert not api.produce.called + + +def test_valid_repofile_exists(monkeypatch): + def _mocked_parse_repofile(fpath): + return RepositoryFile(file=fpath, data=_REPODATA) + monkeypatch.setattr(os.path, 'isfile', lambda dummy: True) + monkeypatch.setattr(api, 'produce', produce_mocked()) + monkeypatch.setattr(repofileutils, 'parse_repofile', _mocked_parse_repofile) + monkeypatch.setattr(api, 'current_logger', LoggerMocked()) + scancustomrepofile.process() + msg = "The {} file exists, custom repositories loaded.".format(scancustomrepofile.CUSTOM_REPO_PATH) + assert api.current_logger.infomsg == msg + assert api.produce.called == len(_CUSTOM_REPOS) + 1 + assert _CUSTOM_REPO_FILE_MSG in api.produce.model_instances + for crepo in _CUSTOM_REPOS: + assert crepo in api.produce.model_instances + + +def test_target_stable_repos(monkeypatch): + def _mocked_parse_repofile(fpath): + return RepositoryFile(file=fpath, data=_TESTING_REPODATA) + monkeypatch.setattr(os.path, 'isfile', lambda dummy: True) + monkeypatch.setattr(api, 'produce', produce_mocked()) + monkeypatch.setattr(repofileutils, 'parse_repofile', _mocked_parse_repofile) + + scancustomrepofile.process(_PROCESS_STABLE_TARGET) + assert api.produce.called == len(_TESTING_CUSTOM_REPOS_STABLE_TARGET) + 1 + for crepo in _TESTING_CUSTOM_REPOS_STABLE_TARGET: + assert crepo in api.produce.model_instances + + +def test_target_beta_repos(monkeypatch): + def _mocked_parse_repofile(fpath): + return RepositoryFile(file=fpath, data=_TESTING_REPODATA) + monkeypatch.setattr(os.path, 'isfile', lambda dummy: True) + monkeypatch.setattr(api, 'produce', produce_mocked()) + monkeypatch.setattr(repofileutils, 'parse_repofile', _mocked_parse_repofile) + + scancustomrepofile.process(_PROCESS_BETA_TARGET) + assert api.produce.called == len(_TESTING_CUSTOM_REPOS_BETA_TARGET) + 1 + for crepo in _TESTING_CUSTOM_REPOS_BETA_TARGET: + assert crepo in api.produce.model_instances + + +def test_empty_repofile_exists(monkeypatch): + def _mocked_parse_repofile(fpath): + return RepositoryFile(file=fpath, data=[]) + monkeypatch.setattr(os.path, 'isfile', lambda dummy: True) + monkeypatch.setattr(api, 'produce', produce_mocked()) + monkeypatch.setattr(repofileutils, 'parse_repofile', _mocked_parse_repofile) + monkeypatch.setattr(api, 'current_logger', LoggerMocked()) + scancustomrepofile.process() + msg = "The {} file exists, but is empty. Nothing to do.".format(scancustomrepofile.CUSTOM_REPO_PATH) + assert api.current_logger.infomsg == msg + assert not api.produce.called diff --git a/repos/system_upgrade/common/actors/setuptargetrepos/actor.py b/repos/system_upgrade/common/actors/setuptargetrepos/actor.py index 91855818..3a7e955b 100644 --- a/repos/system_upgrade/common/actors/setuptargetrepos/actor.py +++ b/repos/system_upgrade/common/actors/setuptargetrepos/actor.py @@ -10,7 +10,8 @@ from leapp.models import ( RHUIInfo, SkippedRepositories, TargetRepositories, - UsedRepositories + UsedRepositories, + VendorCustomTargetRepositoryList ) from leapp.tags import FactsPhaseTag, IPUWorkflowTag @@ -37,7 +38,8 @@ class SetupTargetRepos(Actor): RepositoriesFacts, RepositoriesBlacklisted, RHUIInfo, - UsedRepositories) + UsedRepositories, + VendorCustomTargetRepositoryList) produces = (TargetRepositories, SkippedRepositories) tags = (IPUWorkflowTag, FactsPhaseTag) diff --git a/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos.py b/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos.py index a6073aa3..dfa565c1 100644 --- a/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos.py +++ b/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos.py @@ -1,6 +1,7 @@ from leapp.libraries.actor import setuptargetrepos_repomap from leapp.libraries.common.config.version import get_source_major_version, get_source_version, get_target_version +from leapp.libraries.common.repomaputils import combine_repomap_messages from leapp.libraries.stdlib import api from leapp.models import ( CustomTargetRepository, @@ -13,7 +14,8 @@ from leapp.models import ( RHUIInfo, SkippedRepositories, TargetRepositories, - UsedRepositories + UsedRepositories, + VendorCustomTargetRepositoryList ) RHUI_CLIENT_REPOIDS_RHEL88_TO_RHEL810 = { @@ -80,13 +82,62 @@ def _get_mapped_repoids(repomap, src_repoids): return mapped_repoids +def _get_vendor_custom_repos(enabled_repos, mapping_list): + # Look at what source repos from the vendor mapping were enabled. + # If any of them are in beta, include vendor's custom repos in the list. + # Otherwise skip them. + + result = [] + + # Build a dict of vendor mappings for easy lookup. + map_dict = {mapping.vendor: mapping for mapping in mapping_list if mapping.vendor} + + for vendor_repolist in api.consume(VendorCustomTargetRepositoryList): + vendor_repomap = map_dict[vendor_repolist.vendor] + + # Find the beta channel repositories for the vendor. + beta_repos = [ + x.repoid for x in vendor_repomap.repositories if x.channel == "beta" + ] + api.current_logger().debug( + "Vendor {} beta repos: {}".format(vendor_repolist.vendor, beta_repos) + ) + + # Are any of the beta repos present and enabled on the system? + if any(rep in beta_repos for rep in enabled_repos): + # If so, use all repos including beta in the upgrade. + vendor_repos = vendor_repolist.repos + else: + # Otherwise filter beta repos out. + vendor_repos = [repo for repo in vendor_repolist.repos if repo.repoid not in beta_repos] + + result.extend([CustomTargetRepository( + repoid=repo.repoid, + name=repo.name, + baseurl=repo.baseurl, + enabled=repo.enabled, + ) for repo in vendor_repos]) + + return result + + def process(): # Load relevant data from messages used_repoids_dict = _get_used_repo_dict() enabled_repoids = _get_enabled_repoids() excluded_repoids = _get_blacklisted_repoids() + + # Remember that we can't just grab one message, each vendor can have its own mapping. + repo_mapping_list = list(api.consume(RepositoriesMapping)) + custom_repos = _get_custom_target_repos() repoids_from_installed_packages = _get_repoids_from_installed_packages() + vendor_repos = _get_vendor_custom_repos(enabled_repoids, repo_mapping_list) + custom_repos.extend(vendor_repos) + + api.current_logger().debug( + "Vendor repolist: {}".format([repo.repoid for repo in vendor_repos]) + ) # Setup repomap handler repo_mappig_msg = next(api.consume(RepositoriesMapping), RepositoriesMapping()) @@ -168,6 +219,10 @@ def process(): custom_repos = [repo for repo in custom_repos if repo.repoid not in excluded_repoids] custom_repos = sorted(custom_repos, key=lambda x: x.repoid) + api.current_logger().debug( + "Final repolist: {}".format([repo.repoid for repo in custom_repos]) + ) + # produce message about skipped repositories enabled_repoids_with_mapping = _get_mapped_repoids(repomap, enabled_repoids) skipped_repoids = enabled_repoids & set(used_repoids_dict.keys()) - enabled_repoids_with_mapping diff --git a/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_repomapping.py b/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_repomapping.py index af40c443..1b0a3122 100644 --- a/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_repomapping.py +++ b/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_repomapping.py @@ -75,6 +75,9 @@ def repomap_data_multiple_distros(): make_pesid_repo("pesid3", "10", "pesid3-repoid-eus", channel="eus"), make_pesid_repo("pesid3", "10", "pesid3-repoid-aws", rhui="aws"), make_pesid_repo("pesid3", "10", "pesid3-repoid-centos", distro="centos"), + make_pesid_repo("pesid1", "9", "pesid1-repoid-almalinux", distro="almalinux"), + make_pesid_repo("pesid2", "10", "pesid2-repoid-almalinux", distro="almalinux"), + make_pesid_repo("pesid3", "10", "pesid3-repoid-almalinux", distro="almalinux"), ], ) return repomap_data @@ -106,7 +109,7 @@ def test_get_pesid_repo_entry(monkeypatch, repomap_data_for_pesid_repo_retrieval assert handler.get_pesid_repo_entry('nonexisting-repo', '7') is None, fail_description -@pytest.mark.parametrize('distro', ('rhel', 'centos')) +@pytest.mark.parametrize('distro', ('rhel', 'centos', 'almalinux')) def test_get_pesid_repo_entry_distro( monkeypatch, repomap_data_multiple_distros, distro ): @@ -163,7 +166,7 @@ def test_get_target_pesids(monkeypatch, repomap_data_for_pesid_repo_retrieval): assert [] == handler.get_target_pesids('pesid_no_mapping'), fail_description -@pytest.mark.parametrize('distro', ('rhel', 'centos')) +@pytest.mark.parametrize('distro', ('rhel', 'centos', 'almalinux')) def test_get_target_pesids_distro( monkeypatch, repomap_data_multiple_distros, distro ): @@ -199,6 +202,7 @@ def test_get_target_pesids_distro( [ ('rhel', [5, 6, 7], [0, 1]), ('centos', [8], [2]), + ('almalinux', [11], [9]), ] ) def test_get_pesid_repos( @@ -251,6 +255,7 @@ def test_get_pesid_repos( [ ('rhel', [0, 1]), ('centos', []), + ('almalinux', []), ] ) def test_get_source_pesid_repos(monkeypatch, repomap_data_for_pesid_repo_retrieval, distro, expected_repos_index): @@ -291,6 +296,7 @@ def test_get_source_pesid_repos(monkeypatch, repomap_data_for_pesid_repo_retriev [ ('rhel', [3, 4, 5]), ('centos', []), + ('almalinux', []), ] ) def test_get_target_pesid_repos(monkeypatch, repomap_data_for_pesid_repo_retrieval, distro, expected_repos_index): diff --git a/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_setuptargetrepos.py b/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_setuptargetrepos.py index 91d9cd24..1f898e8f 100644 --- a/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_setuptargetrepos.py +++ b/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_setuptargetrepos.py @@ -100,94 +100,99 @@ def test_repositories_setup_tasks(monkeypatch): assert rhel_repos[0].repoid == 'rhel-8-server-rpms' -def test_repos_mapping(monkeypatch): +@pytest.mark.parametrize('distro_id', ['rhel', 'centos', 'almalinux']) +def test_repos_mapping_for_distro(monkeypatch, distro_id): """ Tests whether actor correctly determines what repositories should be enabled on target based on the information about what repositories are enabled on the source system using - the RepositoriesMapping information. + the RepositoriesMapping information for a specific distro. """ repos_data = [ - RepositoryData(repoid='rhel-7-server-rpms', name='RHEL 7 Server'), - RepositoryData(repoid='rhel-7-blacklisted-rpms', name='RHEL 7 Blacklisted')] + RepositoryData(repoid='{}-7-server-rpms'.format(distro_id), name='{} 7 Server'.format(distro_id)), + RepositoryData(repoid='{}-7-blacklisted-rpms'.format(distro_id), name='{} 7 Blacklisted'.format(distro_id))] repos_files = [RepositoryFile(file='/etc/yum.repos.d/redhat.repo', data=repos_data)] facts = RepositoriesFacts(repositories=repos_files) installed_rpms = InstalledRPM( - items=[mock_package('foreman', 'rhel-7-for-x86_64-satellite-extras-rpms'), - mock_package('foreman-proxy', 'nosuch-rhel-7-for-x86_64-satellite-extras-rpms')]) + items=[mock_package('foreman', '{}-7-for-x86_64-satellite-extras-rpms'.format(distro_id)), + mock_package('foreman-proxy', 'nosuch-{}-7-for-x86_64-satellite-extras-rpms'.format(distro_id))]) repomap = RepositoriesMapping( - mapping=[RepoMapEntry(source='rhel7-base', target=['rhel8-baseos', 'rhel8-appstream', 'rhel8-blacklist']), - RepoMapEntry(source='rhel7-satellite-extras', target=['rhel8-satellite-extras'])], + mapping=[RepoMapEntry(source='{0}7-base'.format(distro_id), + target=['{0}8-baseos'.format(distro_id), + '{0}8-appstream'.format(distro_id), + '{0}8-blacklist'.format(distro_id)]), + RepoMapEntry(source='{0}7-satellite-extras'.format(distro_id), + target=['{0}8-satellite-extras'.format(distro_id)])], repositories=[ PESIDRepositoryEntry( - pesid='rhel7-base', - repoid='rhel-7-server-rpms', + pesid='{0}7-base'.format(distro_id), + repoid='{0}-7-server-rpms'.format(distro_id), major_version='7', arch='x86_64', repo_type='rpm', channel='ga', rhui='', - distro='rhel', + distro=distro_id, ), PESIDRepositoryEntry( - pesid='rhel8-baseos', - repoid='rhel-8-for-x86_64-baseos-htb-rpms', + pesid='{0}8-baseos'.format(distro_id), + repoid='{0}-8-for-x86_64-baseos-htb-rpms'.format(distro_id), major_version='8', arch='x86_64', repo_type='rpm', channel='ga', rhui='', - distro='rhel', + distro=distro_id, ), PESIDRepositoryEntry( - pesid='rhel8-appstream', - repoid='rhel-8-for-x86_64-appstream-htb-rpms', + pesid='{0}8-appstream'.format(distro_id), + repoid='{0}-8-for-x86_64-appstream-htb-rpms'.format(distro_id), major_version='8', arch='x86_64', repo_type='rpm', channel='ga', rhui='', - distro='rhel', + distro=distro_id, ), PESIDRepositoryEntry( - pesid='rhel8-blacklist', - repoid='rhel-8-blacklisted-rpms', + pesid='{0}8-blacklist'.format(distro_id), + repoid='{0}-8-blacklisted-rpms'.format(distro_id), major_version='8', arch='x86_64', repo_type='rpm', channel='ga', rhui='', - distro='rhel', + distro=distro_id, ), PESIDRepositoryEntry( - pesid='rhel7-satellite-extras', - repoid='rhel-7-for-x86_64-satellite-extras-rpms', + pesid='{0}7-satellite-extras'.format(distro_id), + repoid='{0}-7-for-x86_64-satellite-extras-rpms'.format(distro_id), major_version='7', arch='x86_64', repo_type='rpm', channel='ga', rhui='', - distro='rhel', + distro=distro_id, ), PESIDRepositoryEntry( - pesid='rhel8-satellite-extras', - repoid='rhel-8-for-x86_64-satellite-extras-rpms', + pesid='{0}8-satellite-extras'.format(distro_id), + repoid='{0}-8-for-x86_64-satellite-extras-rpms'.format(distro_id), major_version='8', arch='x86_64', repo_type='rpm', channel='ga', rhui='', - distro='rhel', + distro=distro_id, ), ] ) - repos_blacklisted = RepositoriesBlacklisted(repoids=['rhel-8-blacklisted-rpms']) + repos_blacklisted = RepositoriesBlacklisted(repoids=['{}-8-blacklisted-rpms'.format(distro_id)]) msgs = [facts, repomap, repos_blacklisted, installed_rpms] - monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=msgs)) + monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=msgs, release_id=distro_id)) monkeypatch.setattr(api, 'produce', produce_mocked()) setuptargetrepos.process() @@ -197,6 +202,7 @@ def test_repos_mapping(monkeypatch): assert len(rhel_repos) == 3 produced_rhel_repoids = {repo.repoid for repo in rhel_repos} - expected_rhel_repoids = {'rhel-8-for-x86_64-baseos-htb-rpms', 'rhel-8-for-x86_64-appstream-htb-rpms', - 'rhel-8-for-x86_64-satellite-extras-rpms'} + expected_rhel_repoids = {'{0}-8-for-x86_64-baseos-htb-rpms'.format(distro_id), + '{0}-8-for-x86_64-appstream-htb-rpms'.format(distro_id), + '{0}-8-for-x86_64-satellite-extras-rpms'.format(distro_id)} assert produced_rhel_repoids == expected_rhel_repoids diff --git a/repos/system_upgrade/common/actors/systemfacts/actor.py b/repos/system_upgrade/common/actors/systemfacts/actor.py index 59b12c87..85d4a09e 100644 --- a/repos/system_upgrade/common/actors/systemfacts/actor.py +++ b/repos/system_upgrade/common/actors/systemfacts/actor.py @@ -47,7 +47,7 @@ class SystemFactsActor(Actor): GrubCfgBios, Report ) - tags = (IPUWorkflowTag, FactsPhaseTag,) + tags = (IPUWorkflowTag, FactsPhaseTag.Before,) def process(self): self.produce(systemfacts.get_sysctls_status()) diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py index 9ec4ecac..0b7a5b3a 100644 --- a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py +++ b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py @@ -7,7 +7,7 @@ from leapp import reporting from leapp.exceptions import StopActorExecution, StopActorExecutionError from leapp.libraries.actor import constants from leapp.libraries.common import dnfplugin, mounting, overlaygen, repofileutils, rhsm, utils -from leapp.libraries.common.config import get_env, get_product_type +from leapp.libraries.common.config import get_distro_id, get_env, get_product_type from leapp.libraries.common.config.version import get_target_major_version from leapp.libraries.common.gpg import get_path_to_gpg_certs, is_nogpgcheck_set from leapp.libraries.stdlib import api, CalledProcessError, config, run @@ -152,9 +152,10 @@ def _import_gpg_keys(context, install_root_dir, target_major_version): # Import the RHEL X+1 GPG key to be able to verify the installation of initial packages try: # Import also any other keys provided by the customer in the same directory - for certname in os.listdir(certs_path): - cmd = ['rpm', '--root', install_root_dir, '--import', os.path.join(certs_path, certname)] - context.call(cmd, callback_raw=utils.logging_handler) + for trusted_dir in certs_path: + for certname in os.listdir(trusted_dir): + cmd = ['rpm', '--root', install_root_dir, '--import', os.path.join(trusted_dir, certname)] + context.call(cmd, callback_raw=utils.logging_handler) except CalledProcessError as exc: raise StopActorExecutionError( message=( @@ -641,6 +642,7 @@ def _prep_repository_access(context, target_userspace): run(["chroot", target_userspace, "/bin/bash", "-c", "su - -c update-ca-trust"]) if not rhsm.skip_rhsm(): + _copy_certificates(context, target_userspace) run(['rm', '-rf', os.path.join(target_etc, 'rhsm')]) context.copytree_from('/etc/rhsm', os.path.join(target_etc, 'rhsm')) @@ -673,7 +675,15 @@ def _prep_repository_access(context, target_userspace): def _get_product_certificate_path(): """ Retrieve the required / used product certificate for RHSM. + + Product certificates are only used on RHEL, on non-RHEL systems the function returns None. + + :return: The path to the product certificate or None on non-RHEL systems + :raises: StopActorExecution if a certificate cannot be found """ + if get_distro_id() != 'rhel': + return None + architecture = api.current_actor().configuration.architecture target_version = api.current_actor().configuration.version.target target_product_type = get_product_type('target') @@ -1083,6 +1093,26 @@ def _install_custom_repofiles(context, custom_repofiles): context.copy_to(rfile.file, _dst_path) +def adjust_dnf_stream_variable(context, varfile='/etc/dnf/vars/stream'): + """ + Adjust the version in the dnf 'stream' variable to the target version. + + URLs in CentOS Stream repofiles contain the $stream variable which, + if not adjusted, retains the value from the source system making + the URLs point to repos for the source version. This function adjusts + the variable so that the URLs point to the target version repos. + """ + + target_version = get_target_major_version() + try: + with context.open(varfile, 'w') as f: + f.write(target_version + '-stream\n') + except (FileNotFoundError, OSError) as e: + raise StopActorExecutionError( + message='Failed to adjust dnf variable in {} to "{}".'.format(varfile, target_version + '-stream'), + details={'details': str(e)}) + + def _gather_target_repositories(context, indata, prod_cert_path): """ This is wrapper function to gather the target repoids. @@ -1101,6 +1131,9 @@ def _gather_target_repositories(context, indata, prod_cert_path): rhsm.set_container_mode(context) rhsm.switch_certificate(context, indata.rhsm_info, prod_cert_path) + if api.current_actor().configuration.os_release.release_id == 'centos': + adjust_dnf_stream_variable(context) + _install_custom_repofiles(context, indata.custom_repofiles) return gather_target_repositories(context, indata) diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py b/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py index 267c064e..7853a7ad 100644 --- a/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py +++ b/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py @@ -3,6 +3,7 @@ from __future__ import division, print_function import os import subprocess import sys +import tempfile from collections import namedtuple import pytest @@ -40,6 +41,9 @@ class MockedMountingBase(object): self.called_copytree_from = [] self.target = '' + def open(self, fullpath, *args, **kwargs): + return open(self, fullpath, *args, **kwargs) + def copytree_from(self, src, dst): self.called_copytree_from.append((src, dst)) @@ -876,6 +880,13 @@ def test_get_product_certificate_path(monkeypatch, adjust_cwd, result, dst_ver, assert userspacegen._get_product_certificate_path() in result +def test_get_product_certificate_path_nonrhel(monkeypatch): + actor = CurrentActorMocked(release_id='notrhel') + monkeypatch.setattr(userspacegen.api, 'current_actor', actor) + path = userspacegen._get_product_certificate_path() + assert path is None + + @suppress_deprecation(models.RequiredTargetUserspacePackages) def _gen_packages_msgs(): _cfiles = [ @@ -1207,20 +1218,26 @@ def mocked_consume_data(): # TODO: come up with additional tests for the main function -def test_perform_ok(monkeypatch): +@pytest.mark.parametrize( + "distro,cert_path", [("rhel", _DEFAULT_CERT_PATH), ("centos", None)] +) +def test_perform_ok(monkeypatch, distro, cert_path): repoids = ['repoidX', 'repoidY'] monkeypatch.setattr(userspacegen, '_InputData', mocked_consume_data) - monkeypatch.setattr(userspacegen, '_get_product_certificate_path', lambda: _DEFAULT_CERT_PATH) + monkeypatch.setattr(userspacegen, '_get_product_certificate_path', lambda: cert_path) monkeypatch.setattr(overlaygen, 'create_source_overlay', MockedMountingBase) monkeypatch.setattr(userspacegen, '_gather_target_repositories', lambda *x: repoids) monkeypatch.setattr(userspacegen, '_create_target_userspace', lambda *x: None) monkeypatch.setattr(userspacegen, 'setup_target_rhui_access_if_needed', lambda *x: None) - monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked()) + monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked(release_id=distro)) monkeypatch.setattr(userspacegen.api, 'produce', produce_mocked()) monkeypatch.setattr(repofileutils, 'get_repodirs', lambda: ['/etc/yum.repos.d']) + userspacegen.perform() + msg_target_repos = models.UsedTargetRepositories( repos=[models.UsedTargetRepository(repoid=repo) for repo in repoids]) + assert userspacegen.api.produce.called == 3 assert isinstance(userspacegen.api.produce.model_instances[0], models.TMPTargetRepositoriesFacts) assert userspacegen.api.produce.model_instances[1] == msg_target_repos @@ -1325,3 +1342,52 @@ def test__get_files_owned_by_rpms_recursive(monkeypatch): ) assert has_dbgmsg('SKIP the tls/certs/server.crt file: not owned by any rpm') assert has_dbgmsg('Found the file owned by an rpm: rpm-gpg/RPM-GPG-KEY-2.') + + +def test_writing_stream_varfile(monkeypatch): + + monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked()) + monkeypatch.setattr(userspacegen, 'get_target_major_version', lambda: '10') + + with tempfile.NamedTemporaryFile(mode='w+') as tmpf: + tmpf.write('incorrect-stream-value\n') + tmpf.flush() + userspacegen.adjust_dnf_stream_variable(MockedMountingBase, tmpf.name) + tmpf.seek(0) + content = tmpf.read() + + assert content == '10-stream\n' + + +def test_failing_stream_varfile_write(monkeypatch): + monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked()) + monkeypatch.setattr(userspacegen, 'get_target_major_version', lambda: '10') + with pytest.raises(StopActorExecutionError) as err: + userspacegen.adjust_dnf_stream_variable(MockedMountingBase, '/path/not/exists') + + assert 'Failed to adjust dnf variable' in str(err.value) + + +@pytest.mark.parametrize("distro,should_adjust", [('rhel', False), ('centos', True)]) +def test_if_adjust_dnf_stream_variable_only_for_centos(monkeypatch, distro, should_adjust): + + def do_nothing(*args, **kwargs): + pass + + def mock_adjust_stream_variable(context, varfile='/etc/dnf/vars/stream'): + assert varfile == '/etc/dnf/vars/stream' + nonlocal adjust_called + adjust_called = True + + monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked(release_id=distro)) + monkeypatch.setattr(userspacegen, 'get_target_major_version', lambda: '10') + monkeypatch.setattr(rhsm, 'set_container_mode', do_nothing) + monkeypatch.setattr(rhsm, 'switch_certificate', do_nothing) + monkeypatch.setattr(userspacegen, '_install_custom_repofiles', do_nothing) + monkeypatch.setattr(userspacegen, 'adjust_dnf_stream_variable', mock_adjust_stream_variable) + monkeypatch.setattr(userspacegen, 'gather_target_repositories', do_nothing) + + adjust_called = False + + userspacegen._gather_target_repositories(MockedMountingBase, testInData, None) + assert adjust_called == should_adjust diff --git a/repos/system_upgrade/common/actors/trustedgpgkeysscanner/libraries/trustedgpgkeys.py b/repos/system_upgrade/common/actors/trustedgpgkeysscanner/libraries/trustedgpgkeys.py index 6377f767..4c5420f6 100644 --- a/repos/system_upgrade/common/actors/trustedgpgkeysscanner/libraries/trustedgpgkeys.py +++ b/repos/system_upgrade/common/actors/trustedgpgkeysscanner/libraries/trustedgpgkeys.py @@ -13,13 +13,14 @@ def _get_pubkeys(installed_rpms): pubkeys = get_pubkeys_from_rpms(installed_rpms) db_pubkeys = [key.fingerprint for key in pubkeys] certs_path = get_path_to_gpg_certs() - for certname in os.listdir(certs_path): - key_file = os.path.join(certs_path, certname) - fps = get_gpg_fp_from_file(key_file) - for fp in fps: - if fp not in db_pubkeys: - pubkeys.append(GpgKey(fingerprint=fp, rpmdb=False, filename=key_file)) - db_pubkeys += fp + for trusted_dir in certs_path: + for certname in os.listdir(trusted_dir): + key_file = os.path.join(trusted_dir, certname) + fps = get_gpg_fp_from_file(key_file) + for fp in fps: + if fp not in db_pubkeys: + pubkeys.append(GpgKey(fingerprint=fp, rpmdb=False, filename=key_file)) + db_pubkeys += fp return pubkeys diff --git a/repos/system_upgrade/common/actors/vendorreposignaturescanner/actor.py b/repos/system_upgrade/common/actors/vendorreposignaturescanner/actor.py new file mode 100644 index 00000000..dbf86974 --- /dev/null +++ b/repos/system_upgrade/common/actors/vendorreposignaturescanner/actor.py @@ -0,0 +1,72 @@ +import os + +from leapp.actors import Actor +from leapp.models import VendorSignatures, ActiveVendorList +from leapp.tags import FactsPhaseTag, IPUWorkflowTag + + +VENDORS_DIR = "/etc/leapp/files/vendors.d/" +SIGFILE_SUFFIX = ".sigs" + + +class VendorRepoSignatureScanner(Actor): + """ + Produce VendorSignatures messages for the vendor signature files inside the + . + These messages are used to extend the list of pakcages Leapp will consider + signed and will attempt to upgrade. + + The messages are produced only if a "from" vendor repository + listed indide its map matched one of the repositories active on the system. + """ + + name = 'vendor_repo_signature_scanner' + consumes = (ActiveVendorList) + produces = (VendorSignatures) + tags = (IPUWorkflowTag, FactsPhaseTag.Before) + + def process(self): + if not os.path.isdir(VENDORS_DIR): + self.log.debug( + "The {} directory doesn't exist. Nothing to do.".format(VENDORS_DIR) + ) + return + + active_vendors = [] + for vendor_list in self.consume(ActiveVendorList): + active_vendors.extend(vendor_list.data) + + self.log.debug( + "Active vendor list: {}".format(active_vendors) + ) + + for sigfile_name in os.listdir(VENDORS_DIR): + if not sigfile_name.endswith(SIGFILE_SUFFIX): + continue + # Cut the suffix part to get only the name. + vendor_name = sigfile_name[:-5] + + if vendor_name not in active_vendors: + self.log.debug( + "Vendor {} not in active list, skipping".format(vendor_name) + ) + continue + + self.log.debug( + "Vendor {} found in active list, processing file {}".format(vendor_name, sigfile_name) + ) + + full_sigfile_path = os.path.join(VENDORS_DIR, sigfile_name) + with open(full_sigfile_path) as f: + signatures = [line for line in f.read().splitlines() if line] + + self.produce( + VendorSignatures( + vendor=vendor_name, + sigs=signatures, + ) + ) + + self.log.info( + "The {} directory exists, vendor signatures loaded.".format(VENDORS_DIR) + ) diff --git a/repos/system_upgrade/common/actors/vendorrepositoriesmapping/actor.py b/repos/system_upgrade/common/actors/vendorrepositoriesmapping/actor.py new file mode 100644 index 00000000..13256476 --- /dev/null +++ b/repos/system_upgrade/common/actors/vendorrepositoriesmapping/actor.py @@ -0,0 +1,19 @@ +from leapp.actors import Actor +# from leapp.libraries.common.repomaputils import scan_vendor_repomaps, VENDOR_REPOMAP_DIR +from leapp.libraries.actor.vendorrepositoriesmapping import scan_vendor_repomaps +from leapp.models import VendorSourceRepos, RepositoriesMapping +from leapp.tags import FactsPhaseTag, IPUWorkflowTag + + +class VendorRepositoriesMapping(Actor): + """ + Scan the vendor repository mapping files and provide the data to other actors. + """ + + name = "vendor_repositories_mapping" + consumes = () + produces = (RepositoriesMapping, VendorSourceRepos,) + tags = (IPUWorkflowTag, FactsPhaseTag.Before) + + def process(self): + scan_vendor_repomaps() diff --git a/repos/system_upgrade/common/actors/vendorrepositoriesmapping/libraries/vendorrepositoriesmapping.py b/repos/system_upgrade/common/actors/vendorrepositoriesmapping/libraries/vendorrepositoriesmapping.py new file mode 100644 index 00000000..6a41d4e5 --- /dev/null +++ b/repos/system_upgrade/common/actors/vendorrepositoriesmapping/libraries/vendorrepositoriesmapping.py @@ -0,0 +1,92 @@ +import os +import json + +from leapp.libraries.common import fetch +from leapp.libraries.common.config.version import get_target_major_version, get_source_major_version +from leapp.libraries.common.repomaputils import RepoMapData +from leapp.libraries.stdlib import api +from leapp.models import VendorSourceRepos, RepositoriesMapping +from leapp.models.fields import ModelViolationError +from leapp.exceptions import StopActorExecutionError + + +VENDORS_DIR = "/etc/leapp/files/vendors.d" +"""The folder containing the vendor repository mapping files.""" + + +def inhibit_upgrade(msg): + raise StopActorExecutionError( + msg, + details={'hint': ('Read documentation at the following link for more' + ' information about how to retrieve the valid file:' + ' https://access.redhat.com/articles/3664871')}) + + +def read_repofile(repofile, repodir): + try: + return json.loads(fetch.read_or_fetch(repofile, directory=repodir, allow_download=False)) + except ValueError: + # The data does not contain a valid json + inhibit_upgrade('The repository mapping file is invalid: file does not contain a valid JSON object.') + return None + + +def read_repomap_file(repomap_file, read_repofile_func, vendor_name): + json_data = read_repofile_func(repomap_file, VENDORS_DIR) + try: + repomap_data = RepoMapData.load_from_dict(json_data) + + source_major = get_source_major_version() + target_major = get_target_major_version() + + api.produce(VendorSourceRepos( + vendor=vendor_name, + source_repoids=repomap_data.get_version_repoids(source_major) + )) + + mapping = repomap_data.get_mappings(source_major, target_major) + valid_major_versions = [source_major, target_major] + + api.produce(RepositoriesMapping( + mapping=mapping, + repositories=repomap_data.get_repositories(valid_major_versions), + vendor=vendor_name + )) + except ModelViolationError as err: + err_message = ( + 'The repository mapping file is invalid: ' + 'the JSON does not match required schema (wrong field type/value): {}. ' + 'Ensure that the current upgrade path is correct and is present in the mappings: {} -> {}' + .format(err, source_major, target_major) + ) + inhibit_upgrade(err_message) + except KeyError as err: + inhibit_upgrade( + 'The repository mapping file is invalid: the JSON is missing a required field: {}'.format(err)) + except ValueError as err: + # The error should contain enough information, so we do not need to clarify it further + inhibit_upgrade('The repository mapping file is invalid: {}'.format(err)) + + +def scan_vendor_repomaps(read_repofile_func=read_repofile): + """ + Scan the repository mapping file and produce RepositoriesMapping msg. + + See the description of the actor for more details. + """ + + map_json_suffix = "_map.json" + if os.path.isdir(VENDORS_DIR): + vendor_mapfiles = list(filter(lambda vfile: map_json_suffix in vfile, os.listdir(VENDORS_DIR))) + + for mapfile in vendor_mapfiles: + read_repomap_file(mapfile, read_repofile_func, mapfile[:-len(map_json_suffix)]) + else: + api.current_logger().debug( + "The {} directory doesn't exist. Nothing to do.".format(VENDORS_DIR) + ) + # vendor_repomap_collection = scan_vendor_repomaps(VENDOR_REPOMAP_DIR) + # if vendor_repomap_collection: + # self.produce(vendor_repomap_collection) + # for repomap in vendor_repomap_collection.maps: + # self.produce(repomap) diff --git a/repos/system_upgrade/common/files/distro/almalinux/gpg-signatures.json b/repos/system_upgrade/common/files/distro/almalinux/gpg-signatures.json new file mode 100644 index 00000000..0629d123 --- /dev/null +++ b/repos/system_upgrade/common/files/distro/almalinux/gpg-signatures.json @@ -0,0 +1,26 @@ +{ + "keys": [ + "51d6647ec21ad6ea", + "d36cb86cb86b3716", + "2ae81e8aced7258b", + "429785e181b961a5", + "d07bf2a08d50eb66" + ], + "obsoleted-keys": { + "7": [], + "8": [ + "gpg-pubkey-2fa658e0-45700c69", + "gpg-pubkey-37017186-45761324", + "gpg-pubkey-db42a60e-37ea5438" + ], + "9": [ + "gpg-pubkey-d4082792-5b32db75", + "gpg-pubkey-3abb34f8-5ffd890e", + "gpg-pubkey-6275f250-5e26cb2e", + "gpg-pubkey-73e3b907-6581b071", + "gpg-pubkey-ced7258b-6525146f" + ], + "10": ["gpg-pubkey-b86b3716-61e69f29"] + } + +} diff --git a/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/10/RPM-GPG-KEY-AlmaLinux-10 b/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/10/RPM-GPG-KEY-AlmaLinux-10 new file mode 100644 index 00000000..5228281c --- /dev/null +++ b/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/10/RPM-GPG-KEY-AlmaLinux-10 @@ -0,0 +1,29 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGaP6O8BEACvg8IlAxGayV8zOi9Ex+Pd8lrj2BrBzloG8ri84ORp9o8ojq7l +ykKmIElHe11cQD2Lf/a4lcQQ4Ec3baiD786X6K2eVSlBEAnZMzfjDg8R63SfsBuu +8Yk+lUyqlBrDnSDYaPruOAzLIz2r82ikIC1jDbipZsMFPFHPI4/hayyWxJ3oGxRe +0mbtYLB9ElEKngt+/hfo7JLklakbznyIRuVEF3VrZb91XC6r/idqfJoNyBXSKidj +z0IwqOhgkLUk84rzltDo3AzwGqusd7PEuhOmqinOhp0hMdXsztD4TVyhw82iXu/O +onOAObZTZYfM6Z8btmDqkoo0aT+oPPCuZ3yC/caU9dhvCSXET/CGoXc3hL55u9PV +qmcVm/mwvuEImEAvxVc0/dBzEUk+FwW8KsaN3HoUKrC4/NqgmaQz8/42np7u2j+B +OOJ4hAckNEdWd8rB86CYN00sdxnvLBsp8V3IwEqXLhGOoBsagy61Z8hKCM+siOGn +xmbbybgaLOs+DPlxt9LrtgLJHODwmD96oysUPJuA0lv8KMiSpId0tSpp9Wn/wHBG +kRgxGYfzQu7WRvRZqQaleft1JTXXOjNzPur0RkJyb3yFwAoxpePyo/WrupM41OHW +58cEqdC6riCnJcS4U84RLj+hwvufBVB7areQ75sETnKeyozZW+P16E1t/wARAQAB +tChBbG1hTGludXggT1MgMTAgPHBhY2thZ2VyQGFsbWFsaW51eC5vcmc+iQJMBBMB +CgA2FiEE7m23uY9b9e3Z2g3l3uXBHMKh5XIFAmaP6O8CGwMECwkIBwQVCgkIBRYC +AwEAAh4FAheAAAoJEN7lwRzCoeVy32AP/A2+KI+JhmsxnactSptkAWGyAAf1YBWW +Js2sc9OJdKj7uIkzszCx7c7VIVeF/VLijIYpM/zwUgir5S5SimzQmY+FumwbKIml +K5RBsoSog22i7Edho0MLa1pa6qvnKS0nkl9DEcu8EbMUhucWbxGnCG/22EEMTrY+ +Si1IZNkDGtlBHHBKMC+STbqqTxtdy4tAd2NYwWh3sBIh6PF7T4NLRAugu7PZQr5K +amS4z2lV3ebshGjieA0Zoznwh0AXgN0gZ/0pC/LXI25gcgtrvkCyL8Fe0AyZUMd8 +UvZXaRSsm3SkCUIlGjPrvuItn1D7tHmqVSCDKXDM2TqjfiRm1JF+2OFCBNvGz19V +LxWd/Gf+0qw0dtKxRMKzGh0mxXY40hjtmYZulrPxhG5itNDjStovgrevM1HBsXs9 +ikrkOGQ0pFcqizTn4ZKAmMozEMuIuV89Vof2bBCg7pHT1FmXVdAaYJxb6a7A/CgN +qHjoh8AxBiGw/Q2NM4YJlUVhHqqd+/lUG3WJqACNEnqSlZkYQ3HqNNaKhHVbD4mN +q/g6v+f8aWWDZDsI6IAfbJUB+KPEnIvQJQleWuHrq7kcUMhEq3dwBMIoTVEHhUUr +RQKToSEM1rN7PcanaXQM2gy141dS7tFLxhapG8ug75LkIUnEOpPMtUjvrU1ZELGq +36vVHBB+dTDg +=tJCw +-----END PGP PUBLIC KEY BLOCK----- diff --git a/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/9/RPM-GPG-KEY-AlmaLinux-9 b/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/9/RPM-GPG-KEY-AlmaLinux-9 new file mode 100644 index 00000000..d4165d58 --- /dev/null +++ b/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/9/RPM-GPG-KEY-AlmaLinux-9 @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGHmnykBEACuIcqcNYTmu2q58XI5NRZowdJGAxxs+6ExX7qsa4vbPp6St7lB +JmLpwf5p6czIBhLL4b8E7zJpu57tVDo7Ejw6Hv584rbI8vw7pnMTe6XUFhMTL8FT +lyAmn8xAIlcyM+SzshnxAc5b8E0p/egMonr3J1QnvMSfixMQ59GrmLVyece7Vv3J +4fREh6k31kg7eQdEkzRQhRdO2KyxWYLR0A6haXSXVaiBOjFF7iUs7anlJSfeD3FO +afPq0Ix8oWi+mUc4txkABMdsGpdkE/MHOwN90FB8EG5XVrdv3emm3yzKMMzb53Yd +jcf0fovIeRloQyl9+CrVCnkBjFcIFBZZddsB43kM7eTflmAQ+tanOZ8OKBRPMtmI +56b/vk31ozHUoST/NmjbEI5tu+QYCuFSZ++mC06qJg0Bkw821DTAsM7Kynuj7K2f +WWQjlDL9ZsFifLqDXRymL+sn6g142hHQOa5KSHtT7cAcrm6L48gEL3fPntVSOU/H +BlTnODiSSTIsIRNA7kBkbSP3wWoYC1JQPmNYbUtZ7va2uXNb9dGT2k7Ae0465WND +wqRQJDxsr6TLYFpti+JRaOpSMNclXz4kRSP263Y4ZzQvkMGgSgwqg7JU00Uahk2p +KTlJAA8AiaMBdShlo/QXvL29Lyg0Y5klq2HCNziJDupWhXto5j5pjixrpwARAQAB +tCdBbG1hTGludXggT1MgOSA8cGFja2FnZXJAYWxtYWxpbnV4Lm9yZz6JAk4EEwEI +ADgWIQS/GKwodheJCNbnEmfTbLhsuGs3FgUCYeafKQIbAwULCQgHAgYVCgkICwIE +FgIDAQIeAQIXgAAKCRDTbLhsuGs3FrvnD/9X1wDM/C214t3UVsMVjTLdIJDGG+iU +E7Uk7QGeyeNif19rRatzXUHBBGjiAwpxe2rkveWBHCHPSUKqsAR9Arv3nMKiaGfA +0nomzDndLEDIgv35xzaU6OhX95mZzvj+9PThuxDxUnsNoA+7vGkaiRw+cyyDdTJQ +bKwum8bx1gS8Kbqo9mqrMekQ4NHCodq9bb2hI6pAxlYa472QuwFAXFAzbE3LIMIK +hzLkew7nxwP0txP/zzqPw4lYN38fg9AlHL2qgf0twCFO4N/ftkw25qwoiBhiwaWT +Ca8Z9wUJx35Z/ufscbNrtRrIGYNXTDFJdGY/WxKDp7QsyOx/sclcsSksKoC/52tL +2yFLQrMXsqnLjAQajA6adaeCAAwvp2/8VP8R65O4KMuKghMneCGwXVlVVYyRUXJD +Kjg7EvmmMGuh/Lj2A/vj+mQMmlS2kAl0qOsK9DtUIA7Z9m98zI3UmN/5BMb/HdqW +KADagOW9IPyo6IaSIT+A+7npTN1Y7m1aIrL1vsAKrus4MrCvAs1vYqzqIikv88Di +EWYVFCWTsTWf7jxBCVTLn1Lr7Mj08i+7OgRgguQGpcnvKsbwq1v2whQrs+YKR9hP +vVaW5DmGJ5brPykJUaQS6p5Esp1q3HBk0HbBxiiGIwGsKbLp0pKsk5TLzMIJwIG/ +lEolCV+fJ0P4nLkCDQRh5p8pARAAvXTL29arJ5Dl9FXVpE4Km1jJLaK2WfbQARJz +ygQKps9QNqS1yz7C7mYdTtgRxeK2eqcX5oA83w3ppJ0DTsxfAkY3nqAXS8+QRORU +ffSFvhdsU1G/qpvhX0Aq62gr4y1bkIMr9GlLq86uVKIQrNdmto4NDfQc1bDD5e4j +KaNMmNLXxq/s67AxFW/yLchYYZ7cMqQd6Ab4lacqpGdYFIAkBkVMmj3GUSo+FLpl ++4c50AZ8O0aB+xkrjch+4PoVyIpIC1IuqNYBYn2wMYFB414QY2iDopzpZXUhpCqx +NP4Zyhl1noUcOtH/wUfH1JsIcYRn0ixWF6JnE9KmjpkqBuM2/4Ot/bl67iPiN/if +vf3Z1kYjNPaszoMW3kmJj8MlBCSH9w6nQRG/eikihbeUDBB6rh2O7Dz8ltFqlt8N +asbngRoNZMnWMnItRV67Fo0pfn/DZA8VvI029apE21sNp6l7MUa8Z2/I/PNq10E8 +rPMQM//k9y2kgxz52i6iCyesobPvun6UC4xuFoYKUTQMgKQgqOhyZ4evkepFhmHg +Gzx+F8EmwN1FtxfNxfLtQZSUT3kxuUDizwpaH/LkSkRXpJOQyHJL6VBINNTjB4j1 +3+0jD+lCV6xIt88NYkGJL9rtKwZLQHSDPiI0ooCJ69GKy8SmSx04AwSsY67In1q8 ++FQjT20AEQEAAYkCNgQYAQgAIBYhBL8YrCh2F4kI1ucSZ9NsuGy4azcWBQJh5p8p +AhsMAAoJENNsuGy4azcW0KkP/i0YLRv+pDiSC4034oboczAnNrzJnBhqTi9cUEGn +Xpqvf/Zz3opqvRQiqZAgVcCtxfW+P9J3Vb/mBJ6OkR/jywAlY5il2dzK08YfVXmP +cEf6RF4M0KNtlYJmPlnQCZjMJaisrPmYD3Yy8ER1qJ5JQZ7n0REHZCbBCqH8w+5r +j4ohEHY7xXbd7+tvWTCk2MkHaide/UV/04WiO064AoZSUze/vaAx8Ll4AyFpxuIk +ktXZXbq7MaVzqYYJptiRB6TljzMwIbblLm9A7T7YTA/1rNe12OhDT8VoR3gG2C/l +Mtf37EmYq3QVqFlbj4+ouQWIiQmp5dQenH5ugf+Bob7IiENpxzF1cIu6wd4p5Y64 +3cdYUoxrjhsCM6W1lSqECoN8yXJnRTxpBwwm65SVk477KS2h77aJfa+v5UnBhpSt +eVlAhs0A8Qp/hX3o7qMO1jWca3zdJwXppLlFEYTVaFUOUrc4Lhlbi0gAnn8aBwSx +xF1r5GhPGIBzHtRgulwZkmS6VwtDMuC6KlrASu9f93D5gLZqVk22Oar9LpgCEACd +8Gw/+BFbdANqo9IKmDrWf7k/YuEqZ3h+eoyKI/2z7dKh/fcVEydMTn3LB4nFRvSD +AZ27tvC0IUXCUNx7iJdrD5kDsMhZRl5/dXbe539G4y2W00QYuJC0DpUvGdtOuaFx +1WKL +=jk2t +-----END PGP PUBLIC KEY BLOCK----- diff --git a/repos/system_upgrade/common/files/distro/centos/gpg-signatures.json b/repos/system_upgrade/common/files/distro/centos/gpg-signatures.json index 547b13e7..6dfa5b0f 100644 --- a/repos/system_upgrade/common/files/distro/centos/gpg-signatures.json +++ b/repos/system_upgrade/common/files/distro/centos/gpg-signatures.json @@ -2,7 +2,24 @@ "keys": [ "24c6a8a7f4a80eb5", "05b555b38483c65d", - "4eb84e71f2ee9d55" + "4eb84e71f2ee9d55", + "429785e181b961a5", + "d07bf2a08d50eb66", + "6c7cb6ef305d49d6" ], - "obsoleted-keys": {} + "obsoleted-keys": { + "7": [], + "8": [ + "gpg-pubkey-2fa658e0-45700c69", + "gpg-pubkey-37017186-45761324", + "gpg-pubkey-db42a60e-37ea5438" + ], + "9": [ + "gpg-pubkey-d4082792-5b32db75", + "gpg-pubkey-3abb34f8-5ffd890e", + "gpg-pubkey-6275f250-5e26cb2e", + "gpg-pubkey-73e3b907-6581b071" + ], + "10": ["gpg-pubkey-8483c65d-5ccc5b19"] + } } diff --git a/repos/system_upgrade/common/files/distro/cloudlinux/gpg-signatures.json b/repos/system_upgrade/common/files/distro/cloudlinux/gpg-signatures.json new file mode 100644 index 00000000..acad9006 --- /dev/null +++ b/repos/system_upgrade/common/files/distro/cloudlinux/gpg-signatures.json @@ -0,0 +1,22 @@ +{ + "keys": [ + "8c55a6628608cb71", + "d07bf2a08d50eb66", + "429785e181b961a5" + ], + "obsoleted-keys": { + "7": [], + "8": [ + "gpg-pubkey-2fa658e0-45700c69", + "gpg-pubkey-37017186-45761324", + "gpg-pubkey-db42a60e-37ea5438" + ], + "9": [ + "gpg-pubkey-d4082792-5b32db75", + "gpg-pubkey-3abb34f8-5ffd890e", + "gpg-pubkey-6275f250-5e26cb2e", + "gpg-pubkey-73e3b907-6581b071" + ], + "10": [] + } +} diff --git a/repos/system_upgrade/common/files/distro/ol/gpg-signatures.json b/repos/system_upgrade/common/files/distro/ol/gpg-signatures.json new file mode 100644 index 00000000..a53775cf --- /dev/null +++ b/repos/system_upgrade/common/files/distro/ol/gpg-signatures.json @@ -0,0 +1,24 @@ +{ + "keys": [ + "72f97b74ec551f03", + "82562ea9ad986da3", + "bc4d06a08d8b756f", + "429785e181b961a5", + "d07bf2a08d50eb66" + ], + "obsoleted-keys": { + "7": [], + "8": [ + "gpg-pubkey-2fa658e0-45700c69", + "gpg-pubkey-37017186-45761324", + "gpg-pubkey-db42a60e-37ea5438" + ], + "9": [ + "gpg-pubkey-d4082792-5b32db75", + "gpg-pubkey-3abb34f8-5ffd890e", + "gpg-pubkey-6275f250-5e26cb2e", + "gpg-pubkey-73e3b907-6581b071" + ], + "10": [] + } +} diff --git a/repos/system_upgrade/common/files/distro/rhel/gpg-signatures.json b/repos/system_upgrade/common/files/distro/rhel/gpg-signatures.json index 3cc67f82..c1f4acf4 100644 --- a/repos/system_upgrade/common/files/distro/rhel/gpg-signatures.json +++ b/repos/system_upgrade/common/files/distro/rhel/gpg-signatures.json @@ -4,7 +4,9 @@ "5326810137017186", "938a80caf21541eb", "fd372689897da07a", - "45689c882fa658e0" + "45689c882fa658e0", + "429785e181b961a5", + "d07bf2a08d50eb66" ], "obsoleted-keys": { "7": [], @@ -13,7 +15,12 @@ "gpg-pubkey-37017186-45761324", "gpg-pubkey-db42a60e-37ea5438" ], - "9": ["gpg-pubkey-d4082792-5b32db75"], + "9": [ + "gpg-pubkey-d4082792-5b32db75", + "gpg-pubkey-3abb34f8-5ffd890e", + "gpg-pubkey-6275f250-5e26cb2e", + "gpg-pubkey-73e3b907-6581b071" + ], "10": ["gpg-pubkey-fd431d51-4ae0493b"] } } diff --git a/repos/system_upgrade/common/files/distro/rocky/gpg-signatures.json b/repos/system_upgrade/common/files/distro/rocky/gpg-signatures.json new file mode 100644 index 00000000..f1738e79 --- /dev/null +++ b/repos/system_upgrade/common/files/distro/rocky/gpg-signatures.json @@ -0,0 +1,23 @@ +{ + "keys": [ + "15af5dac6d745a60", + "702d426d350d275d", + "429785e181b961a5", + "d07bf2a08d50eb66" + ], + "obsoleted-keys": { + "7": [], + "8": [ + "gpg-pubkey-2fa658e0-45700c69", + "gpg-pubkey-37017186-45761324", + "gpg-pubkey-db42a60e-37ea5438" + ], + "9": [ + "gpg-pubkey-d4082792-5b32db75", + "gpg-pubkey-3abb34f8-5ffd890e", + "gpg-pubkey-6275f250-5e26cb2e", + "gpg-pubkey-73e3b907-6581b071" + ], + "10": [] + } +} diff --git a/repos/system_upgrade/common/files/distro/scientific/gpg-signatures.json b/repos/system_upgrade/common/files/distro/scientific/gpg-signatures.json new file mode 100644 index 00000000..df764b53 --- /dev/null +++ b/repos/system_upgrade/common/files/distro/scientific/gpg-signatures.json @@ -0,0 +1,22 @@ +{ + "keys": [ + "b0b4183f192a7d7d", + "429785e181b961a5", + "d07bf2a08d50eb66" + ], + "obsoleted-keys": { + "7": [], + "8": [ + "gpg-pubkey-2fa658e0-45700c69", + "gpg-pubkey-37017186-45761324", + "gpg-pubkey-db42a60e-37ea5438" + ], + "9": [ + "gpg-pubkey-d4082792-5b32db75", + "gpg-pubkey-3abb34f8-5ffd890e", + "gpg-pubkey-6275f250-5e26cb2e", + "gpg-pubkey-73e3b907-6581b071" + ], + "10": [] + } +} diff --git a/repos/system_upgrade/common/files/rhel_upgrade.py b/repos/system_upgrade/common/files/rhel_upgrade.py index 4f76a61d..27824406 100644 --- a/repos/system_upgrade/common/files/rhel_upgrade.py +++ b/repos/system_upgrade/common/files/rhel_upgrade.py @@ -185,6 +185,7 @@ class RhelUpgradeCommand(dnf.cli.Command): to_install = self.plugin_data['pkgs_info']['to_install'] to_remove = self.plugin_data['pkgs_info']['to_remove'] to_upgrade = self.plugin_data['pkgs_info']['to_upgrade'] + to_reinstall = self.plugin_data['pkgs_info']['to_reinstall'] # Modules to enable self._process_entities(entities=[available_modules_to_enable], @@ -197,6 +198,9 @@ class RhelUpgradeCommand(dnf.cli.Command): self._process_entities(entities=to_install, op=self.base.install, entity_name='Package') # Packages to be upgraded self._process_entities(entities=to_upgrade, op=self.base.upgrade, entity_name='Package') + # Packages to be reinstalled + self._process_entities(entities=to_reinstall, op=self.base.reinstall, entity_name='Package') + self.base.distro_sync() if self.opts.tid[0] == 'check': diff --git a/repos/system_upgrade/common/files/upgrade_paths.json b/repos/system_upgrade/common/files/upgrade_paths.json index 279e6eaa..47ca28d5 100644 --- a/repos/system_upgrade/common/files/upgrade_paths.json +++ b/repos/system_upgrade/common/files/upgrade_paths.json @@ -2,8 +2,9 @@ "rhel": { "default": { "7.9": ["8.10"], - "8.10": ["9.4", "9.6"], + "8.10": ["9.4", "9.6", "9.7"], "9.6": ["10.0"], + "9.7": ["10.1"], "7": ["8.10"], "8": ["9.4", "9.6"], "9": ["10.0"] @@ -24,8 +25,15 @@ }, "_virtual_versions": { "8": "8.10", - "9": "9.6", - "10": "10.0" + "9": "9.7", + "10": "10.1" + } + }, + "almalinux": { + "default": { + "8.10": ["9.0", "9.1", "9.2", "9.3", "9.4", "9.5", "9.6", "9.7"], + "9.6": ["10.0"], + "9.7": ["10.0", "10.1"] } } } diff --git a/repos/system_upgrade/common/libraries/config/__init__.py b/repos/system_upgrade/common/libraries/config/__init__.py index 38519d7b..0c737f93 100644 --- a/repos/system_upgrade/common/libraries/config/__init__.py +++ b/repos/system_upgrade/common/libraries/config/__init__.py @@ -97,3 +97,16 @@ def get_target_product_channel(default='ga'): def get_consumed_data_stream_id(): """Get the identifier of the asset family used by leapp.""" return CONSUMED_DATA_STREAM_ID + + +def get_distro_id(): + """ + Retrieve the distro ID. + + This is the ID string from /etc/os_release. + E.g. "rhel" for Red Hat Enterprise Linux + + :return: The ID string from /etc/os_release + :rtype: str + """ + return api.current_actor().configuration.os_release.release_id diff --git a/repos/system_upgrade/common/libraries/distro.py b/repos/system_upgrade/common/libraries/distro.py index 2ed5eacd..219d31d1 100644 --- a/repos/system_upgrade/common/libraries/distro.py +++ b/repos/system_upgrade/common/libraries/distro.py @@ -3,6 +3,7 @@ import os from leapp.exceptions import StopActorExecutionError from leapp.libraries.stdlib import api +from leapp.models import VendorSignatures def get_distribution_data(distribution): @@ -11,8 +12,14 @@ def get_distribution_data(distribution): distribution_config = os.path.join(distributions_path, distribution, 'gpg-signatures.json') if os.path.exists(distribution_config): with open(distribution_config) as distro_config_file: - return json.load(distro_config_file) + distro_config_json = json.load(distro_config_file) else: raise StopActorExecutionError( 'Cannot find distribution signature configuration.', details={'Problem': 'Distribution {} was not found in {}.'.format(distribution, distributions_path)}) + + # Extend with Vendors signatures + for siglist in api.consume(VendorSignatures): + distro_config_json["keys"].extend(siglist.sigs) + + return distro_config_json diff --git a/repos/system_upgrade/common/libraries/dnfplugin.py b/repos/system_upgrade/common/libraries/dnfplugin.py index 4f0c3a99..0f31f101 100644 --- a/repos/system_upgrade/common/libraries/dnfplugin.py +++ b/repos/system_upgrade/common/libraries/dnfplugin.py @@ -90,6 +90,7 @@ def build_plugin_data(target_repoids, debug, test, tasks, on_aws): 'to_install': sorted(tasks.to_install), 'to_remove': sorted(tasks.to_remove), 'to_upgrade': sorted(tasks.to_upgrade), + 'to_reinstall': sorted(tasks.to_reinstall), 'modules_to_enable': sorted(['{}:{}'.format(m.name, m.stream) for m in tasks.modules_to_enable]), }, 'dnf_conf': { diff --git a/repos/system_upgrade/common/libraries/fetch.py b/repos/system_upgrade/common/libraries/fetch.py index 82bf4ff3..cb20d775 100644 --- a/repos/system_upgrade/common/libraries/fetch.py +++ b/repos/system_upgrade/common/libraries/fetch.py @@ -146,7 +146,8 @@ def load_data_asset(actor_requesting_asset, asset_filename, asset_fulltext_name, docs_url, - docs_title): + docs_title, + asset_directory="/etc/leapp/files"): """ Load the content of the data asset with given asset_filename and produce :class:`leapp.model.ConsumedDataAsset` message. @@ -183,7 +184,7 @@ def load_data_asset(actor_requesting_asset, try: # The asset family ID has the form (major, minor), include only `major` in the URL - raw_asset_contents = read_or_fetch(asset_filename, data_stream=data_stream_major, allow_download=False) + raw_asset_contents = read_or_fetch(asset_filename, directory=asset_directory, data_stream=data_stream_major, allow_download=False) asset_contents = json.loads(raw_asset_contents) except ValueError: msg = 'The {0} file (at {1}) does not contain a valid JSON object.'.format(asset_fulltext_name, asset_filename) diff --git a/repos/system_upgrade/common/libraries/gpg.py b/repos/system_upgrade/common/libraries/gpg.py index c9c3f1fc..96907be0 100644 --- a/repos/system_upgrade/common/libraries/gpg.py +++ b/repos/system_upgrade/common/libraries/gpg.py @@ -122,12 +122,15 @@ def get_path_to_gpg_certs(): if target_product_type == 'beta': certs_dir = '{}beta'.format(target_major_version) distro = api.current_actor().configuration.os_release.release_id - return os.path.join( - api.get_common_folder_path('distro'), - distro, - GPG_CERTS_FOLDER, - certs_dir - ) + return [ + "/etc/leapp/files/vendors.d/rpm-gpg/", + os.path.join( + api.get_common_folder_path('distro'), + distro, + GPG_CERTS_FOLDER, + certs_dir + ) + ] def is_nogpgcheck_set(): diff --git a/repos/system_upgrade/common/libraries/repomaputils.py b/repos/system_upgrade/common/libraries/repomaputils.py new file mode 100644 index 00000000..39b7d662 --- /dev/null +++ b/repos/system_upgrade/common/libraries/repomaputils.py @@ -0,0 +1,141 @@ +from collections import defaultdict +from leapp.models import PESIDRepositoryEntry, RepoMapEntry, RepositoriesMapping + +class RepoMapData(object): + VERSION_FORMAT = '1.3.0' + + def __init__(self): + self.repositories = [] + self.mapping = {} + + def add_repository(self, data, pesid): + """ + Add new PESIDRepositoryEntry with given pesid from the provided dictionary. + + :param data: A dict containing the data of the added repository. The dictionary structure corresponds + to the repositories entries in the repository mapping JSON schema. + :type data: Dict[str, str] + :param pesid: PES id of the repository family that the newly added repository belongs to. + :type pesid: str + """ + self.repositories.append(PESIDRepositoryEntry( + repoid=data['repoid'], + channel=data['channel'], + rhui=data.get('rhui', ''), + repo_type=data['repo_type'], + arch=data['arch'], + major_version=data['major_version'], + pesid=pesid, + distro=data['distro'], + )) + + def get_repositories(self, valid_major_versions): + """ + Return the list of PESIDRepositoryEntry object matching the specified major versions. + """ + return [repo for repo in self.repositories if repo.major_version in valid_major_versions] + + def get_version_repoids(self, major_version): + """ + Return the list of repository ID strings for repositories matching the specified major version. + """ + return [repo.repoid for repo in self.repositories if repo.major_version == major_version] + + def add_mapping(self, source_major_version, target_major_version, source_pesid, target_pesid): + """ + Add a new mapping entry that is mapping the source pesid to the destination pesid(s), + relevant in an IPU from the supplied source major version to the supplied target + major version. + + :param str source_major_version: Specifies the major version of the source system + for which the added mapping applies. + :param str target_major_version: Specifies the major version of the target system + for which the added mapping applies. + :param str source_pesid: PESID of the source repository. + :param Union[str|List[str]] target_pesid: A single target PESID or a list of target + PESIDs of the added mapping. + """ + # NOTE: it could be more simple, but I prefer to be sure the input data + # contains just one map per source PESID. + key = '{}:{}'.format(source_major_version, target_major_version) + rmap = self.mapping.get(key, defaultdict(set)) + self.mapping[key] = rmap + if isinstance(target_pesid, list): + rmap[source_pesid].update(target_pesid) + else: + rmap[source_pesid].add(target_pesid) + + def get_mappings(self, src_major_version, dst_major_version): + """ + Return the list of RepoMapEntry objects for the specified upgrade path. + + IOW, the whole mapping for specified IPU. + """ + key = '{}:{}'.format(src_major_version, dst_major_version) + rmap = self.mapping.get(key, None) + if not rmap: + return None + map_list = [] + for src_pesid in sorted(rmap.keys()): + map_list.append(RepoMapEntry(source=src_pesid, target=sorted(rmap[src_pesid]))) + return map_list + + @staticmethod + def load_from_dict(data): + if data['version_format'] != RepoMapData.VERSION_FORMAT: + raise ValueError( + 'The obtained repomap data has unsupported version of format.' + ' Get {} required {}' + .format(data['version_format'], RepoMapData.VERSION_FORMAT) + ) + + repomap = RepoMapData() + + # Load reposiories + existing_pesids = set() + for repo_family in data['repositories']: + existing_pesids.add(repo_family['pesid']) + for repo in repo_family['entries']: + repomap.add_repository(repo, repo_family['pesid']) + + # Load mappings + for mapping in data['mapping']: + for entry in mapping['entries']: + if not isinstance(entry['target'], list): + raise ValueError( + 'The target field of a mapping entry is not a list: {}' + .format(entry) + ) + + for pesid in [entry['source']] + entry['target']: + if pesid not in existing_pesids: + raise ValueError( + 'The {} pesid is not related to any repository.' + .format(pesid) + ) + repomap.add_mapping( + source_major_version=mapping['source_major_version'], + target_major_version=mapping['target_major_version'], + source_pesid=entry['source'], + target_pesid=entry['target'], + ) + return repomap + +def combine_repomap_messages(mapping_list): + """ + Combine multiple RepositoryMapping messages into one. + Needed because we might get more than one message if there are vendors present. + """ + combined_mapping = [] + combined_repositories = [] + # Depending on whether there are any vendors present, we might get more than one message. + for msg in mapping_list: + combined_mapping.extend(msg.mapping) + combined_repositories.extend(msg.repositories) + + combined_repomapping = RepositoriesMapping( + mapping=combined_mapping, + repositories=combined_repositories + ) + + return combined_repomapping diff --git a/repos/system_upgrade/common/libraries/rhsm.py b/repos/system_upgrade/common/libraries/rhsm.py index e7b074aa..79164cca 100644 --- a/repos/system_upgrade/common/libraries/rhsm.py +++ b/repos/system_upgrade/common/libraries/rhsm.py @@ -7,7 +7,7 @@ import time from leapp import reporting from leapp.exceptions import StopActorExecutionError from leapp.libraries.common import repofileutils -from leapp.libraries.common.config import get_env +from leapp.libraries.common.config import get_distro_id, get_env from leapp.libraries.stdlib import api, CalledProcessError from leapp.models import RHSMInfo @@ -331,10 +331,19 @@ def set_container_mode(context): /etc/pki/entitlement directories exists, even when leapp is executed with --no-rhsm option. If any of these directories are missing, skip other actions - most likely RHSM is not installed in such a case. + Note that this only true on RHEL systems, on non-RHEL (which don't use RHSM) + this function does nothing. :param context: An instance of a mounting.IsolatedActions class :type context: mounting.IsolatedActions class """ + # this has to happen even with skip_rhsm, but only on RHEL + if get_distro_id() != 'rhel': + api.current_logger().info( + 'Skipping setting RHSM into container mode on non-RHEL systems.' + ) + return + if not context.is_isolated(): api.current_logger().error('Trying to set RHSM into the container mode' 'on host. Skipping the action.') diff --git a/repos/system_upgrade/common/libraries/rhui.py b/repos/system_upgrade/common/libraries/rhui.py index b3225d5f..5c293304 100644 --- a/repos/system_upgrade/common/libraries/rhui.py +++ b/repos/system_upgrade/common/libraries/rhui.py @@ -252,6 +252,17 @@ RHUI_SETUPS = { ('cdn.redhat.com-chain.crt', RHUI_PKI_DIR), ('content-rhel9-sap-bundle-e4s.crt', RHUI_PKI_PRODUCT_DIR) ], os_version='9', content_channel=ContentChannel.E4S), + mk_rhui_setup(clients={'rh-amazon-rhui-client-sap-bundle-e4s'}, leapp_pkg='leapp-rhui-aws-sap-e4s', + mandatory_files=[ + ('rhui-client-config-server-10-sap-bundle.crt', RHUI_PKI_PRODUCT_DIR), + ('rhui-client-config-server-10-sap-bundle.key', RHUI_PKI_DIR), + ('leapp-aws-sap-e4s.repo', YUM_REPOS_PATH) + ], + optional_files=[ + ('content-rhel10-sap-bundle-e4s.key', RHUI_PKI_DIR), + ('cdn.redhat.com-chain.crt', RHUI_PKI_DIR), + ('content-rhel10-sap-bundle-e4s.crt', RHUI_PKI_PRODUCT_DIR) + ], os_version='10', content_channel=ContentChannel.E4S), ], RHUIFamily(RHUIProvider.AZURE, client_files_folder='azure'): [ mk_rhui_setup(clients={'rhui-azure-rhel7'}, os_version='7', @@ -312,6 +323,17 @@ RHUI_SETUPS = { ], extra_info={'agent_pkg': 'WALinuxAgent'}, os_version='9', content_channel=ContentChannel.EUS), + mk_rhui_setup(clients={'rhui-azure-rhel10-sapapps'}, leapp_pkg='leapp-rhui-azure-sap', + mandatory_files=[ + ('leapp-azure-sap-apps.repo', YUM_REPOS_PATH), + ('RPM-GPG-KEY-microsoft-azure-release-new', '/etc/pki/rpm-gpg/') + ], + optional_files=[ + ('key-sapapps.pem', RHUI_PKI_DIR), + ('content-sapapps.crt', RHUI_PKI_PRODUCT_DIR) + ], + extra_info={'agent_pkg': 'WALinuxAgent'}, + os_version='10', content_channel=ContentChannel.EUS), ], RHUIFamily(RHUIProvider.AZURE, variant=RHUIVariant.SAP_HA, client_files_folder='azure-sap-ha'): [ mk_rhui_setup(clients={'rhui-azure-rhel7-base-sap-ha'}, os_version='7', content_channel=ContentChannel.E4S), @@ -339,6 +361,17 @@ RHUI_SETUPS = { ], extra_info={'agent_pkg': 'WALinuxAgent'}, os_version='9', content_channel=ContentChannel.E4S), + mk_rhui_setup(clients={'rhui-azure-rhel10-sap-ha'}, leapp_pkg='leapp-rhui-azure-sap', + mandatory_files=[ + ('leapp-azure-sap-ha.repo', YUM_REPOS_PATH), + ('RPM-GPG-KEY-microsoft-azure-release-new', '/etc/pki/rpm-gpg/') + ], + optional_files=[ + ('key-sap-ha.pem', RHUI_PKI_DIR), + ('content-sap-ha.crt', RHUI_PKI_PRODUCT_DIR) + ], + extra_info={'agent_pkg': 'WALinuxAgent'}, + os_version='10', content_channel=ContentChannel.E4S), ], RHUIFamily(RHUIProvider.GOOGLE, client_files_folder='google'): [ mk_rhui_setup(clients={'google-rhui-client-rhel7'}, os_version='7'), diff --git a/repos/system_upgrade/common/libraries/rpms.py b/repos/system_upgrade/common/libraries/rpms.py index dde4d2b6..bd3a2961 100644 --- a/repos/system_upgrade/common/libraries/rpms.py +++ b/repos/system_upgrade/common/libraries/rpms.py @@ -28,9 +28,9 @@ _LEAPP_PACKAGES_MAP = { }, LeappComponents.REPOSITORY: {'7': {'pkgs': ['leapp-upgrade-el7toel8'], 'deps': ['leapp-upgrade-el7toel8-deps']}, - '8': {'pkgs': ['leapp-upgrade-el8toel9'], + '8': {'pkgs': ['leapp-upgrade-el8toel9', 'leapp-upgrade-el8toel9-fapolicyd'], 'deps': ['leapp-upgrade-el8toel9-deps']}, - '9': {'pkgs': ['leapp-upgrade-el9toel10'], + '9': {'pkgs': ['leapp-upgrade-el9toel10', 'leapp-upgrade-el9toel10-fapolicyd'], 'deps': ['leapp-upgrade-el9toel10-deps']} }, LeappComponents.COCKPIT: {'7': {'pkgs': ['cockpit-leapp']}, @@ -87,7 +87,7 @@ def create_lookup(model, field, keys, context=stdlib.api): def has_package(model, package_name, arch=None, version=None, release=None, context=stdlib.api): """ - Expects a model DistributionSignedRPM or InstalledUnsignedRPM. + Expects a DistributionSignedRPM or ThirdPartyRPM model. Can be useful in cases like a quick item presence check, ex. check in actor that a certain package is installed. diff --git a/repos/system_upgrade/common/libraries/tests/test_gpg.py b/repos/system_upgrade/common/libraries/tests/test_gpg.py index 82b51abb..47617ad8 100644 --- a/repos/system_upgrade/common/libraries/tests/test_gpg.py +++ b/repos/system_upgrade/common/libraries/tests/test_gpg.py @@ -18,6 +18,8 @@ from leapp.models import GpgKey, InstalledRPM, RPM ('9.2', 'ga', 'rhel', '../../files/distro/rhel/rpm-gpg/9'), ('10.0', 'ga', 'rhel', '../../files/distro/rhel/rpm-gpg/10'), ('10', 'ga', 'centos', '../../files/distro/centos/rpm-gpg/10'), + ('9.6', 'ga', 'almalinux', '../../files/distro/almalinux/rpm-gpg/9'), + ('10.0', 'ga', 'almalinux', '../../files/distro/almalinux/rpm-gpg/10'), ]) def test_get_path_to_gpg_certs(monkeypatch, target, product_type, distro, exp): current_actor = CurrentActorMocked(dst_ver=target, release_id=distro, diff --git a/repos/system_upgrade/common/libraries/tests/test_rhsm.py b/repos/system_upgrade/common/libraries/tests/test_rhsm.py index 190fd0de..b643cd0d 100644 --- a/repos/system_upgrade/common/libraries/tests/test_rhsm.py +++ b/repos/system_upgrade/common/libraries/tests/test_rhsm.py @@ -8,7 +8,7 @@ from leapp.exceptions import StopActorExecutionError from leapp.libraries.common import repofileutils, rhsm from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked, logger_mocked from leapp.libraries.stdlib import api, CalledProcessError -from leapp.models import RepositoryData, RepositoryFile +from leapp.models import RepositoryData, RepositoryFile, RHSMInfo from leapp.utils.report import is_inhibitor Repository = namedtuple('Repository', ['repoid', 'file']) @@ -67,10 +67,15 @@ class IsolatedActionsMocked(object): self.commands_called = [] self.call_return = {'stdout': call_stdout, 'stderr': None} self.raise_err = raise_err + self.remove_called = [] + self.copy_to_called = [] # A map from called commands to their mocked output self.mocked_command_call_outputs = dict() + def is_isolated(self): + return True + def call(self, cmd, *args, **dummy_kwargs): self.commands_called.append(cmd) if self.raise_err: @@ -91,6 +96,12 @@ class IsolatedActionsMocked(object): def full_path(self, path): return path + def remove(self, path): + self.remove_called.append(path) + + def copy_to(self, src, dst): + self.copy_to_called.append((src, dst)) + @pytest.fixture def actor_mocked(monkeypatch): @@ -409,3 +420,66 @@ def test_is_registered_error(context_mocked): rhsm.is_rhsm_registered(context_mocked) assert 'A subscription-manager command failed to execute' in str(err) + + +def test_set_container_mode(monkeypatch, context_mocked): + actor = CurrentActorMocked(release_id='rhel') + monkeypatch.setattr(api, 'current_actor', actor) + monkeypatch.setattr( + os.path, "exists", lambda path: path in ("/etc/rhsm", "/etc/pki/entitlement") + ) + + rhsm.set_container_mode(context_mocked) + + assert context_mocked.commands_called == [ + ["ln", "-s", "/etc/rhsm", "/etc/rhsm-host"], + ['ln', '-s', '/etc/pki/entitlement', '/etc/pki/entitlement-host'], + ] + + +def test_set_container_mode_nonrhel_skip(monkeypatch, context_mocked): + actor = CurrentActorMocked(release_id='notrhel') + monkeypatch.setattr(api, 'current_actor', actor) + + rhsm.set_container_mode(context_mocked) + + assert context_mocked.commands_called == [] + + +def mocked_rhsm_info(): + return RHSMInfo( + attached_skus=['SKU1', 'SKU2'], + available_repos=['Repo1', 'Repo2'], + enabled_repos=['Repo2'], + release='7.9', + existing_product_certificates=['Cert1', 'Cert2', 'Cert3'], + sca_detected=True, + ) + + +def test_switch_certificate(monkeypatch, context_mocked, actor_mocked): + monkeypatch.setattr( + os.path, 'isdir', lambda path: path in ('/etc/pki/product', '/etc/pki/product-default') + ) + + cert_path = '/etc/leapp/repos.d/system_upgrade/common/files/prod-certs/10/479.pem' + rhsm.switch_certificate(context_mocked, mocked_rhsm_info(), cert_path) + + assert context_mocked.remove_called == mocked_rhsm_info().existing_product_certificates + assert context_mocked.copy_to_called == [ + (cert_path, os.path.join(target_path, "479.pem")) + for target_path in ("/etc/pki/product", "/etc/pki/product-default") + ] + + +def test_switch_certificate_respect_with_rhsm(monkeypatch, context_mocked): + """Test whether switch_certificate is skipped when LEAPP_NO_RHSM=1""" + + mocked_actor = CurrentActorMocked(envars={'LEAPP_NO_RHSM': '1'}) + monkeypatch.setattr(api, 'current_actor', mocked_actor) + + cert_path = '/etc/leapp/repos.d/system_upgrade/common/files/prod-certs/10/479.pem' + rhsm.switch_certificate(context_mocked, mocked_rhsm_info(), cert_path) + + assert context_mocked.remove_called == [] + assert context_mocked.copy_to_called == [] diff --git a/repos/system_upgrade/common/libraries/tests/test_rpms.py b/repos/system_upgrade/common/libraries/tests/test_rpms.py index a527407d..13f87651 100644 --- a/repos/system_upgrade/common/libraries/tests/test_rpms.py +++ b/repos/system_upgrade/common/libraries/tests/test_rpms.py @@ -37,10 +37,10 @@ def test_parse_config_modification(): @pytest.mark.parametrize('major_version,component,result', [ - (None, None, ['leapp', 'python3-leapp', 'leapp-upgrade-el8toel9', 'snactor']), + (None, None, ['leapp', 'python3-leapp', 'leapp-upgrade-el8toel9', 'leapp-upgrade-el8toel9-fapolicyd', 'snactor']), ('7', None, ['leapp', 'python2-leapp', 'leapp-upgrade-el7toel8', 'snactor']), (['7', '8'], None, ['leapp', 'python2-leapp', 'leapp-upgrade-el7toel8', - 'python3-leapp', 'leapp-upgrade-el8toel9', 'snactor']), + 'python3-leapp', 'leapp-upgrade-el8toel9', 'leapp-upgrade-el8toel9-fapolicyd', 'snactor']), ('8', 'framework', ['leapp', 'python3-leapp']), ]) def test_get_leapp_packages(major_version, component, result, monkeypatch): diff --git a/repos/system_upgrade/common/models/activevendorlist.py b/repos/system_upgrade/common/models/activevendorlist.py new file mode 100644 index 00000000..de4056fb --- /dev/null +++ b/repos/system_upgrade/common/models/activevendorlist.py @@ -0,0 +1,7 @@ +from leapp.models import Model, fields +from leapp.topics import VendorTopic + + +class ActiveVendorList(Model): + topic = VendorTopic + data = fields.List(fields.String()) diff --git a/repos/system_upgrade/common/models/initramfs.py b/repos/system_upgrade/common/models/initramfs.py index 03b71125..b65cca33 100644 --- a/repos/system_upgrade/common/models/initramfs.py +++ b/repos/system_upgrade/common/models/initramfs.py @@ -3,6 +3,15 @@ from leapp.topics import BootPrepTopic, SystemInfoTopic from leapp.utils.deprecation import deprecated +# Note that this is the only model about the source (rather than upgrade) initramfs +class DefaultInitramfsInfo(Model): + """ Information about the initramfs image that corresponds to the default source boot entry """ + topic = SystemInfoTopic + + path = fields.String() + used_dracut_modules = fields.List(fields.String(), default=[]) + + class DracutModule(Model): """ Specify a dracut module that should be included into the initramfs diff --git a/repos/system_upgrade/common/models/installedrpm.py b/repos/system_upgrade/common/models/installedrpm.py index cc9fd508..5f18951a 100644 --- a/repos/system_upgrade/common/models/installedrpm.py +++ b/repos/system_upgrade/common/models/installedrpm.py @@ -23,13 +23,30 @@ class InstalledRPM(Model): class DistributionSignedRPM(InstalledRPM): + """ + Installed packages signed by the vendor of the distribution. + """ pass -@deprecated(since='2024-01-31', message='Replaced by DistributionSignedRPM') -class InstalledRedHatSignedRPM(InstalledRPM): +class ThirdPartyRPM(InstalledRPM): + """ + Installed packages not signed by the vendor of the distribution. + + This includes: + - packages signed by other distribution vendors + - packages signed by other software vendors + - unsigned packages + From the POV of in-place upgrades such packages are considered third-party. + + This does not include: + - packages known not to be signed as they are created by a delivered + product (which is possibly part of the distribution). E.g. katello RPMS + created in a Satellite server. + """ pass +@deprecated(since='2025-07-09', message='Replaced by ThirdPartyRPM') class InstalledUnsignedRPM(InstalledRPM): pass diff --git a/repos/system_upgrade/common/models/repositoriesmap.py b/repos/system_upgrade/common/models/repositoriesmap.py index 842cd807..fc740606 100644 --- a/repos/system_upgrade/common/models/repositoriesmap.py +++ b/repos/system_upgrade/common/models/repositoriesmap.py @@ -96,3 +96,4 @@ class RepositoriesMapping(Model): mapping = fields.List(fields.Model(RepoMapEntry), default=[]) repositories = fields.List(fields.Model(PESIDRepositoryEntry), default=[]) + vendor = fields.Nullable(fields.String()) diff --git a/repos/system_upgrade/common/models/rpmtransactiontasks.py b/repos/system_upgrade/common/models/rpmtransactiontasks.py index 7e2870d0..05d4e941 100644 --- a/repos/system_upgrade/common/models/rpmtransactiontasks.py +++ b/repos/system_upgrade/common/models/rpmtransactiontasks.py @@ -10,6 +10,7 @@ class RpmTransactionTasks(Model): to_keep = fields.List(fields.String(), default=[]) to_remove = fields.List(fields.String(), default=[]) to_upgrade = fields.List(fields.String(), default=[]) + to_reinstall = fields.List(fields.String(), default=[]) modules_to_enable = fields.List(fields.Model(Module), default=[]) modules_to_reset = fields.List(fields.Model(Module), default=[]) diff --git a/repos/system_upgrade/common/models/source_boot_entry.py b/repos/system_upgrade/common/models/source_boot_entry.py new file mode 100644 index 00000000..31a8584f --- /dev/null +++ b/repos/system_upgrade/common/models/source_boot_entry.py @@ -0,0 +1,10 @@ +from leapp.models import fields, Model +from leapp.topics import SystemInfoTopic + + +class DefaultSourceBootEntry(Model): + """ Default boot entry of the source system. """ + topic = SystemInfoTopic + + initramfs_path = fields.String() + kernel_path = fields.String() diff --git a/repos/system_upgrade/common/models/targetrepositories.py b/repos/system_upgrade/common/models/targetrepositories.py index 02c6c5e5..f9fd4238 100644 --- a/repos/system_upgrade/common/models/targetrepositories.py +++ b/repos/system_upgrade/common/models/targetrepositories.py @@ -21,6 +21,12 @@ class CustomTargetRepository(TargetRepositoryBase): enabled = fields.Boolean(default=True) +class VendorCustomTargetRepositoryList(Model): + topic = TransactionTopic + vendor = fields.String() + repos = fields.List(fields.Model(CustomTargetRepository)) + + class TargetRepositories(Model): """ Repositories supposed to be used during the IPU process diff --git a/repos/system_upgrade/common/models/vendorsignatures.py b/repos/system_upgrade/common/models/vendorsignatures.py new file mode 100644 index 00000000..f456aec5 --- /dev/null +++ b/repos/system_upgrade/common/models/vendorsignatures.py @@ -0,0 +1,8 @@ +from leapp.models import Model, fields +from leapp.topics import VendorTopic + + +class VendorSignatures(Model): + topic = VendorTopic + vendor = fields.String() + sigs = fields.List(fields.String()) diff --git a/repos/system_upgrade/common/models/vendorsourcerepos.py b/repos/system_upgrade/common/models/vendorsourcerepos.py new file mode 100644 index 00000000..b7a219b4 --- /dev/null +++ b/repos/system_upgrade/common/models/vendorsourcerepos.py @@ -0,0 +1,12 @@ +from leapp.models import Model, fields +from leapp.topics import VendorTopic + + +class VendorSourceRepos(Model): + """ + This model contains the data on all source repositories associated with a specific vendor. + Its data is used to determine whether the vendor should be included into the upgrade process. + """ + topic = VendorTopic + vendor = fields.String() + source_repoids = fields.List(fields.String()) diff --git a/repos/system_upgrade/common/topics/vendortopic.py b/repos/system_upgrade/common/topics/vendortopic.py new file mode 100644 index 00000000..014b7afb --- /dev/null +++ b/repos/system_upgrade/common/topics/vendortopic.py @@ -0,0 +1,5 @@ +from leapp.topics import Topic + + +class VendorTopic(Topic): + name = 'vendor_topic' diff --git a/repos/system_upgrade/el8toel9/actors/addarmbootloaderworkaround/libraries/addupgradebootloader.py b/repos/system_upgrade/el8toel9/actors/addarmbootloaderworkaround/libraries/addupgradebootloader.py index c076fe6b..2455a2f6 100644 --- a/repos/system_upgrade/el8toel9/actors/addarmbootloaderworkaround/libraries/addupgradebootloader.py +++ b/repos/system_upgrade/el8toel9/actors/addarmbootloaderworkaround/libraries/addupgradebootloader.py @@ -14,6 +14,22 @@ from leapp.libraries.common.grub import ( from leapp.libraries.stdlib import api, CalledProcessError, run from leapp.models import ArmWorkaroundEFIBootloaderInfo, EFIBootEntry, TargetUserSpaceInfo +dirname = { + 'AlmaLinux': 'almalinux', + 'CentOS Linux': 'centos', + 'CentOS Stream': 'centos', + 'Oracle Linux Server': 'redhat', + 'Red Hat Enterprise Linux': 'redhat', + 'Rocky Linux': 'rocky', + 'Scientific Linux': 'redhat', +} + +with open('/etc/system-release', 'r') as sr: + release_line = next(line for line in sr if 'release' in line) + distro = release_line.split(' release ', 1)[0] + +distro_dir = dirname.get(distro, 'default') + UPGRADE_EFI_ENTRY_LABEL = 'Leapp Upgrade' ARM_SHIM_PACKAGE_NAME = 'shim-aa64' @@ -21,7 +37,7 @@ ARM_GRUB_PACKAGE_NAME = 'grub2-efi-aa64' EFI_MOUNTPOINT = '/boot/efi/' LEAPP_EFIDIR_CANONICAL_PATH = os.path.join(EFI_MOUNTPOINT, 'EFI/leapp/') -RHEL_EFIDIR_CANONICAL_PATH = os.path.join(EFI_MOUNTPOINT, 'EFI/redhat/') +RHEL_EFIDIR_CANONICAL_PATH = os.path.join(EFI_MOUNTPOINT, 'EFI/', distro_dir) UPGRADE_BLS_DIR = '/boot/upgrade-loader' CONTAINER_DOWNLOAD_DIR = '/tmp_pkg_download_dir' diff --git a/repos/system_upgrade/el8toel9/actors/removeupgradeefientry/libraries/removeupgradeefientry.py b/repos/system_upgrade/el8toel9/actors/removeupgradeefientry/libraries/removeupgradeefientry.py index daa7b2ca..dd604d8b 100644 --- a/repos/system_upgrade/el8toel9/actors/removeupgradeefientry/libraries/removeupgradeefientry.py +++ b/repos/system_upgrade/el8toel9/actors/removeupgradeefientry/libraries/removeupgradeefientry.py @@ -5,9 +5,25 @@ from leapp.exceptions import StopActorExecutionError from leapp.libraries.stdlib import api, CalledProcessError, run from leapp.models import ArmWorkaroundEFIBootloaderInfo +dirname = { + 'AlmaLinux': 'almalinux', + 'CentOS Linux': 'centos', + 'CentOS Stream': 'centos', + 'Oracle Linux Server': 'redhat', + 'Red Hat Enterprise Linux': 'redhat', + 'Rocky Linux': 'rocky', + 'Scientific Linux': 'redhat', +} + +with open('/etc/system-release', 'r') as sr: + release_line = next(line for line in sr if 'release' in line) + distro = release_line.split(' release ', 1)[0] + +distro_dir = dirname.get(distro, 'default') + EFI_MOUNTPOINT = '/boot/efi/' LEAPP_EFIDIR_CANONICAL_PATH = os.path.join(EFI_MOUNTPOINT, 'EFI/leapp/') -RHEL_EFIDIR_CANONICAL_PATH = os.path.join(EFI_MOUNTPOINT, 'EFI/redhat/') +RHEL_EFIDIR_CANONICAL_PATH = os.path.join(EFI_MOUNTPOINT, 'EFI/', distro_dir) def get_workaround_efi_info(): diff --git a/repos/system_upgrade/el9toel10/actors/check_default_initramfs/actor.py b/repos/system_upgrade/el9toel10/actors/check_default_initramfs/actor.py new file mode 100644 index 00000000..c834c495 --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/check_default_initramfs/actor.py @@ -0,0 +1,22 @@ +from leapp.actors import Actor +from leapp.libraries.actor import check_default_initramfs as check_default_initramfs_lib +from leapp.models import DefaultInitramfsInfo +from leapp.reporting import Report +from leapp.tags import ChecksPhaseTag, IPUWorkflowTag + + +class CheckDefaultInitramfs(Actor): + """ + Checks whether the default initramfs uses problematic dracut modules. + + Checks whether dracut modules that are missing on the target system are used. + If yes, the upgrade is inhibited. + """ + + name = 'check_default_initramfs' + consumes = (DefaultInitramfsInfo,) + produces = (Report,) + tags = (IPUWorkflowTag, ChecksPhaseTag) + + def process(self): + check_default_initramfs_lib.check_default_initramfs() diff --git a/repos/system_upgrade/el9toel10/actors/check_default_initramfs/libraries/check_default_initramfs.py b/repos/system_upgrade/el9toel10/actors/check_default_initramfs/libraries/check_default_initramfs.py new file mode 100644 index 00000000..098b5fde --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/check_default_initramfs/libraries/check_default_initramfs.py @@ -0,0 +1,47 @@ +import os + +from leapp import reporting +from leapp.exceptions import StopActorExecutionError +from leapp.libraries.stdlib import api +from leapp.models import DefaultInitramfsInfo + + +def check_default_initramfs(): + default_initramfs_info = next(api.consume(DefaultInitramfsInfo), None) + if not default_initramfs_info: + msg = 'Actor did not receive information about default boot entry\'s initramfs.' + raise StopActorExecutionError(msg) + + if 'network-legacy' in default_initramfs_info.used_dracut_modules: + summary = ( + f'Initramfs ({default_initramfs_info.path}) of the default boot entry uses dracut ' + 'modules that are missing on the target system. This could cause a fatal ' + 'failure during the upgrade, resulting in unbootable system as ' + 'the missing dracut module could prevent creation of the required target ' + 'initramfs.\n\n' + 'Namely, the legacy-network dracut module is used on this system, which ' + 'could originate from older system installations. The problem is typical ' + 'for RHEL 7 and early RHEL 8 systems that were in-place-upgraded to RHEL 9.' + ) + remediation_hint = ( + 'Remove the dracut config file which adds the `network-legacy` dracut module. ' + 'Then rebuild existing initramfs images to remove the dracut module from them.' + ) + report_fields = [ + reporting.Title('Use of dracut modules that are missing on the target system detected'), + reporting.Summary(summary), + reporting.Severity(reporting.Severity.HIGH), + reporting.Groups([reporting.Groups.BOOT]), + reporting.Remediation(hint=remediation_hint), + reporting.Groups([reporting.Groups.INHIBITOR]), + reporting.ExternalLink( + url='https://access.redhat.com/solutions/7127576', + title='leapp upgrade fails to boot after upgrading to RHEL 10.0' + ) + ] + + usual_definition_file = '/etc/dracut.conf.d/50-network-legacy.conf' + if os.path.exists(usual_definition_file): + report_fields.append(reporting.RelatedResource('file', usual_definition_file)) + + reporting.create_report(report_fields) diff --git a/repos/system_upgrade/el9toel10/actors/check_default_initramfs/tests/test_check_default_initramfs.py b/repos/system_upgrade/el9toel10/actors/check_default_initramfs/tests/test_check_default_initramfs.py new file mode 100644 index 00000000..d28ae308 --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/check_default_initramfs/tests/test_check_default_initramfs.py @@ -0,0 +1,105 @@ +import os + +import pytest + +from leapp.exceptions import StopActorExecutionError +from leapp.libraries.actor import check_default_initramfs +from leapp.libraries.common import testutils +from leapp.models import DefaultInitramfsInfo +from leapp.utils.report import is_inhibitor + + +def test_no_default_initramfs_info(monkeypatch): + """Test that StopActorExecutionError is raised when no DefaultInitramfsInfo is provided.""" + # Mock api.consume to return empty iterator + actor_mock = testutils.CurrentActorMocked(msgs=[]) + monkeypatch.setattr(check_default_initramfs.api, 'current_actor', actor_mock) + + with pytest.raises(StopActorExecutionError): + check_default_initramfs.check_default_initramfs() + + +def test_initramfs_without_network_legacy(monkeypatch): + """Test that no report is created when network-legacy module is not present.""" + # Create a DefaultInitramfsInfo without the problematic module + initramfs_info = DefaultInitramfsInfo( + path='/boot/initramfs-upgrade.x86_64.img', + used_dracut_modules=['bash', 'systemd', 'kernel-modules', 'resume'] + ) + + actor_mock = testutils.CurrentActorMocked(msgs=[initramfs_info]) + create_report_mock = testutils.create_report_mocked() + + monkeypatch.setattr(check_default_initramfs.api, 'current_actor', actor_mock) + monkeypatch.setattr(check_default_initramfs.reporting, 'create_report', create_report_mock) + + check_default_initramfs.check_default_initramfs() + + # No report should be created + assert not create_report_mock.called + + +def test_initramfs_with_network_legacy_without_config_file(monkeypatch): + """ + Test that a report is created when network-legacy module is present but config file doesn't exist. + + The typical location of the config file (/etc/dracut.conf.d/50-network-legacy.conf) that + adds the 'network-legacy' module is not present. + """ + # Create a DefaultInitramfsInfo with the problematic module + initramfs_info = DefaultInitramfsInfo( + path='/boot/initramfs-upgrade.x86_64.img', + used_dracut_modules=['bash', 'systemd', 'network-legacy', 'kernel-modules'] + ) + + actor_mock = testutils.CurrentActorMocked(msgs=[initramfs_info]) + create_report_mock = testutils.create_report_mocked() + + monkeypatch.setattr(check_default_initramfs.api, 'current_actor', actor_mock) + monkeypatch.setattr(check_default_initramfs.reporting, 'create_report', create_report_mock) + # Mock os.path.exists to return False for the config file + monkeypatch.setattr(check_default_initramfs.os.path, 'exists', lambda path: False) + + check_default_initramfs.check_default_initramfs() + + assert create_report_mock.called + assert len(create_report_mock.reports) == 1 + + report = create_report_mock.reports[0] + + assert is_inhibitor(report) + + report_resources = report['detail'].get('related_resources', []) + assert not report_resources + + +def test_initramfs_with_network_legacy_with_config_file(monkeypatch): + """Test that a report with related resource is created when network-legacy module and config file are present.""" + initramfs_info = DefaultInitramfsInfo( + path='/boot/initramfs-upgrade.x86_64.img', + used_dracut_modules=['bash', 'systemd', 'network-legacy', 'kernel-modules'] + ) + + actor_mock = testutils.CurrentActorMocked(msgs=[initramfs_info]) + create_report_mock = testutils.create_report_mocked() + + monkeypatch.setattr(check_default_initramfs.api, 'current_actor', actor_mock) + monkeypatch.setattr(check_default_initramfs.reporting, 'create_report', create_report_mock) + + def mock_exists(path): + if path == '/etc/dracut.conf.d/50-network-legacy.conf': + return True + return os.path.exists(path) # Fall back to original implementation since it is used in pytest internally + + monkeypatch.setattr(check_default_initramfs.os.path, 'exists', mock_exists) + + check_default_initramfs.check_default_initramfs() + + assert create_report_mock.called + assert len(create_report_mock.reports) == 1 + + report = create_report_mock.reports[0] + assert is_inhibitor(report) + + report_resources = report['detail'].get('related_resources', []) + assert report_resources diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdchecks/actor.py b/repos/system_upgrade/el9toel10/actors/sssd/sssdchecks/actor.py new file mode 100644 index 00000000..d8cdea8d --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdchecks/actor.py @@ -0,0 +1,20 @@ +from leapp.actors import Actor +from leapp.libraries.actor import sssdchecks +from leapp.models import KnownHostsProxyConfig +from leapp.reporting import Report +from leapp.tags import ChecksPhaseTag, IPUWorkflowTag + + +class SSSDCheck(Actor): + """ + Check SSSD configuration for changes in RHEL10 and report them in model. + """ + + name = 'sssd_check' + consumes = (KnownHostsProxyConfig,) + produces = (Report,) + tags = (IPUWorkflowTag, ChecksPhaseTag) + + def process(self): + for cfg in self.consume(KnownHostsProxyConfig): + sssdchecks.check_config(cfg) diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdchecks/libraries/sssdchecks.py b/repos/system_upgrade/el9toel10/actors/sssd/sssdchecks/libraries/sssdchecks.py new file mode 100644 index 00000000..0a86fa7b --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdchecks/libraries/sssdchecks.py @@ -0,0 +1,33 @@ +from leapp import reporting + +FMT_LIST_SEPARATOR = '\n - ' + + +def check_config(model): + if not model: + return + + # If sss_ssh_knownhostsproxy was not configured, there is nothing to do + if not model.ssh_config_files: + return + + summary = ( + 'SSSD\'s sss_ssh_knownhostsproxy tool is replaced by the more ' + 'reliable sss_ssh_knownhosts tool. SSH\'s configuration will be updated ' + 'to reflect this by updating every mention of sss_ssh_knownhostsproxy by ' + 'the corresponding mention of sss_ssh_knownhosts, even those commented out.\n' + 'SSSD\'s ssh service will be enabled if not already done.\n' + 'The following files will be updated:{}{}'.format( + FMT_LIST_SEPARATOR, + FMT_LIST_SEPARATOR.join(model.sssd_config_files + model.ssh_config_files) + ) + ) + + report = [ + reporting.Title('The sss_ssh_knownhostsproxy will be replaced by sss_ssh_knownhosts'), + reporting.Summary(summary), + reporting.Groups([reporting.Groups.AUTHENTICATION, reporting.Groups.SECURITY]), + reporting.Severity(reporting.Severity.INFO), + ] + + reporting.create_report(report) diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdchecks/tests/component_test_sssdchecks.py b/repos/system_upgrade/el9toel10/actors/sssd/sssdchecks/tests/component_test_sssdchecks.py new file mode 100644 index 00000000..08aa309d --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdchecks/tests/component_test_sssdchecks.py @@ -0,0 +1,29 @@ +from leapp.models import KnownHostsProxyConfig, Report + + +def test_sssdchecks__no_file(current_actor_context): + config = KnownHostsProxyConfig() + current_actor_context.feed(config) + current_actor_context.run() + reports = current_actor_context.consume(Report) + assert not reports + + +def test_sssdchecks__files(current_actor_context): + sssd_files = ['/tmp/file1', '/tmp/file2'] + ssh_files = ['/tmp/file3', '/tmp/file4'] + all_files = sssd_files + ssh_files + + config = KnownHostsProxyConfig(sssd_config_files=sssd_files, ssh_config_files=ssh_files) + current_actor_context.feed(config) + current_actor_context.run() + reports = current_actor_context.consume(Report) + + assert len(reports) == 1 + + report = reports[0].report + assert report['title'] == 'The sss_ssh_knownhostsproxy will be replaced by sss_ssh_knownhosts' + assert 'sss_ssh_knownhosts tool.' in report['summary'] + + FMT_LIST_SEPARATOR = '\n - ' + assert "{}{}".format(FMT_LIST_SEPARATOR, FMT_LIST_SEPARATOR.join(all_files)) in report['summary'] diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/actor.py b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/actor.py new file mode 100644 index 00000000..47fee67a --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/actor.py @@ -0,0 +1,22 @@ +from leapp.actors import Actor +from leapp.libraries.actor import sssdfacts +from leapp.models import KnownHostsProxyConfig +from leapp.tags import FactsPhaseTag, IPUWorkflowTag + + +class SSSDFacts(Actor): + """ + Check SSSD configuration for changes in RHEL10 and report them in model. + + We want to know if the 'ssh' service is enabled and whether ssh was + configured to use the sss_ssh_knownhosts tool. + """ + + name = 'sssd_facts' + consumes = () + produces = (KnownHostsProxyConfig,) + tags = (IPUWorkflowTag, FactsPhaseTag) + + def process(self): + self.produce(sssdfacts.get_facts(['/etc/sssd/sssd.conf', '/etc/sssd/conf.d/'], + ['/etc/ssh/ssh_config', '/etc/ssh/ssh_config.d/'])) diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/libraries/sssdfacts.py b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/libraries/sssdfacts.py new file mode 100644 index 00000000..0ae9d93f --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/libraries/sssdfacts.py @@ -0,0 +1,53 @@ +import os +import re + +from leapp.exceptions import StopActorExecutionError +from leapp.libraries.stdlib import api +from leapp.models import KnownHostsProxyConfig + + +def _does_file_contain_expression(file_path, expression): + try: + with open(file_path) as in_file: + for line in in_file: + if re.search(expression, line) is not None: + return True + return False + except FileNotFoundError: + api.current_logger().warning( + 'Found a file during a recursive walk, but we failed to open it for reading: {}'.format(file_path) + ) + return False + except OSError as e: + raise StopActorExecutionError('Could not open file ' + file_path, details={'details': str(e)}) + + +def _look_for_files(expression: str, path_list: list[str]) -> list[str]: + files_containing_expression = [] + for path in path_list: + if os.path.isdir(path): + for root, dummy_dirs, files in os.walk(path): + for file in files: + full_path = os.path.join(root, file) + if _does_file_contain_expression(full_path, expression): + files_containing_expression.append(full_path) + else: + if _does_file_contain_expression(path, expression): + files_containing_expression.append(path) + + return files_containing_expression + + +def get_facts(sssd_config: list[str], ssh_config: list[str]) -> KnownHostsProxyConfig: + """ + Check SSSD and SSH configuration related to the sss_ssh_knownhostsproxy tool. + + Checks: + - Which files in the SSSD configuration include the `service` keyword, + - Which files in the SSH configuration mention the tool. + """ + + sssd_files = _look_for_files(r'^\s*services\s*=', sssd_config) + ssh_files = _look_for_files(r'^\s*#?\s*ProxyCommand\s+(/usr/bin/)?sss_ssh_knownhostsproxy\s', ssh_config) + + return KnownHostsProxyConfig(sssd_config_files=sssd_files, ssh_config_files=ssh_files) diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/ssh_proxy_disabled.conf b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/ssh_proxy_disabled.conf new file mode 100644 index 00000000..13f757c3 --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/ssh_proxy_disabled.conf @@ -0,0 +1,15 @@ +Host * + ForwardAgent no + ForwardX11 no + PasswordAuthentication yes + HostbasedAuthentication no + GSSAPIAuthentication no + GSSAPIDelegateCredentials no + GSSAPIKeyExchange no + GSSAPITrustDNS no + BatchMode no +# ProxyCommand /usr/bin/sss_ssh_knownhostsproxy -p %p %h + CheckHostIP no + AddressFamily any + ConnectTimeout 0 + StrictHostKeyChecking ask diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/ssh_proxy_enabled.conf b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/ssh_proxy_enabled.conf new file mode 100644 index 00000000..58cc55e5 --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/ssh_proxy_enabled.conf @@ -0,0 +1,15 @@ +Host * + ForwardAgent no + ForwardX11 no + PasswordAuthentication yes + HostbasedAuthentication no + GSSAPIAuthentication no + GSSAPIDelegateCredentials no + GSSAPIKeyExchange no + GSSAPITrustDNS no + BatchMode no + ProxyCommand /usr/bin/sss_ssh_knownhostsproxy -p %p %h + CheckHostIP no + AddressFamily any + ConnectTimeout 0 + StrictHostKeyChecking ask diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/ssh_proxy_not_present.conf b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/ssh_proxy_not_present.conf new file mode 100644 index 00000000..dd97e397 --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/ssh_proxy_not_present.conf @@ -0,0 +1,14 @@ +Host * + ForwardAgent no + ForwardX11 no + PasswordAuthentication yes + HostbasedAuthentication no + GSSAPIAuthentication no + GSSAPIDelegateCredentials no + GSSAPIKeyExchange no + GSSAPITrustDNS no + BatchMode no + CheckHostIP no + AddressFamily any + ConnectTimeout 0 + StrictHostKeyChecking ask diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/sssd_service_disabled.conf b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/sssd_service_disabled.conf new file mode 100644 index 00000000..ad33d8ab --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/sssd_service_disabled.conf @@ -0,0 +1,17 @@ +[sssd] +domains = COMPANY +services = pam,nss + +[domain/COMPANY] +id_provider = ldap +ldap_uri = ldap://ldap.company.com +ldap_search_base = dc=company,dc=com +ldap_tls_cacert = /etc/openldap/cacerts/cacert.pem +ldap_tls_reqcert = never +auth_provider = krb5 +ldap_krb5_keytab = /etc/sssd/company.keytab +krb5_server = hostname +krb5_kpasswd = hostname +krb5_realm = IPA.COMPANY.COM +ldap_sudo_random_offset = 0 +enumerate = false diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/sssd_service_enabled.conf b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/sssd_service_enabled.conf new file mode 100644 index 00000000..63a661a6 --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/sssd_service_enabled.conf @@ -0,0 +1,17 @@ +[sssd] +domains = COMPANY +services = pam,nss,ssh + +[domain/COMPANY] +id_provider = ldap +ldap_uri = ldap://ldap.company.com +ldap_search_base = dc=company,dc=com +ldap_tls_cacert = /etc/openldap/cacerts/cacert.pem +ldap_tls_reqcert = never +auth_provider = krb5 +ldap_krb5_keytab = /etc/sssd/company.keytab +krb5_server = hostname +krb5_kpasswd = hostname +krb5_realm = IPA.COMPANY.COM +ldap_sudo_random_offset = 0 +enumerate = false diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/sssd_service_not_present.conf b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/sssd_service_not_present.conf new file mode 100644 index 00000000..4d014a75 --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/sssd_service_not_present.conf @@ -0,0 +1,16 @@ +[sssd] +domains = COMPANY + +[domain/COMPANY] +id_provider = ldap +ldap_uri = ldap://ldap.company.com +ldap_search_base = dc=company,dc=com +ldap_tls_cacert = /etc/openldap/cacerts/cacert.pem +ldap_tls_reqcert = never +auth_provider = krb5 +ldap_krb5_keytab = /etc/sssd/company.keytab +krb5_server = hostname +krb5_kpasswd = hostname +krb5_realm = IPA.COMPANY.COM +ldap_sudo_random_offset = 0 +enumerate = false diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/subdir/sub_ssh_proxy_enabled.conf b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/subdir/sub_ssh_proxy_enabled.conf new file mode 100644 index 00000000..6acd5a7e --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/files/subdir/sub_ssh_proxy_enabled.conf @@ -0,0 +1,16 @@ +Host * + ForwardAgent no + ForwardX11 no + PasswordAuthentication yes + HostbasedAuthentication no + GSSAPIAuthentication no + GSSAPIDelegateCredentials no + GSSAPIKeyExchange no + GSSAPITrustDNS no + BatchMode no + ProxyCommand /usr/bin/sss_ssh_knownhostsproxy -p %p %h + CheckHostIP no + AddressFamily any + ConnectTimeout 0 + StrictHostKeyChecking ask + diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/unit_test_sssdfacts.py b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/unit_test_sssdfacts.py new file mode 100644 index 00000000..a121d772 --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdfacts/tests/unit_test_sssdfacts.py @@ -0,0 +1,60 @@ +import os + +import pytest + +from leapp.libraries.actor import sssdfacts + +CUR_DIR = os.path.dirname(os.path.abspath(__file__)) + + +def test_sssdfacts__missing_config(): + facts = sssdfacts.get_facts(sssd_config=['/etc/missing-file'], + ssh_config=['/etc/missing-file']) + + assert not facts.sssd_config_files + assert not facts.ssh_config_files + + +def test_sssdfacts__empty_config(): + facts = sssdfacts.get_facts(sssd_config=['/dev/null'], + ssh_config=['/dev/null']) + assert not facts.sssd_config_files + assert not facts.ssh_config_files + + +@pytest.mark.parametrize('state', ['not_present', 'disabled', 'enabled']) +def test_sssdfacts__sssd_service(state): + file = os.path.join(CUR_DIR, 'files', 'sssd_service_' + state + '.conf') + facts = sssdfacts.get_facts(sssd_config=[file], + ssh_config=['/dev/null']) + + if state == 'not_present': + assert not facts.sssd_config_files + else: + assert len(facts.sssd_config_files) == 1 + assert file in facts.sssd_config_files + + +@pytest.mark.parametrize('state', ['not_present', 'disabled', 'enabled']) +def test_sssdfacts__knownhostsproxy(state): + file = os.path.join(CUR_DIR, 'files', 'ssh_proxy_' + state + '.conf') + + facts = sssdfacts.get_facts(sssd_config=['/dev/null'], + ssh_config=[file]) + + if state == 'not_present': + assert not facts.ssh_config_files + else: + assert len(facts.ssh_config_files) == 1 + assert file in facts.ssh_config_files + + +def test_sssdfacts__directory(): + dirpath = os.path.join(CUR_DIR, 'files') + facts = sssdfacts.get_facts(sssd_config=['/dev/null'], + ssh_config=[dirpath]) + + assert len(facts.ssh_config_files) == 3 + assert os.path.join(CUR_DIR, 'files', 'ssh_proxy_disabled.conf') in facts.ssh_config_files + assert os.path.join(CUR_DIR, 'files', 'ssh_proxy_enabled.conf') in facts.ssh_config_files + assert os.path.join(CUR_DIR, 'files', 'subdir', 'sub_ssh_proxy_enabled.conf') in facts.ssh_config_files diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdupdate/actor.py b/repos/system_upgrade/el9toel10/actors/sssd/sssdupdate/actor.py new file mode 100644 index 00000000..7a548f90 --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdupdate/actor.py @@ -0,0 +1,20 @@ +from leapp.actors import Actor +from leapp.libraries.actor import sssdupdate +from leapp.models import KnownHostsProxyConfig +from leapp.tags import ApplicationsPhaseTag, IPUWorkflowTag + + +class SSSDUpdate(Actor): + """ + Update SSSD's and SSH's configuration to use sss_ssh_knownhosts instead + of sss_ssh_knownhosts proxy. + """ + + name = 'sssd_update' + consumes = (KnownHostsProxyConfig,) + produces = () + tags = (IPUWorkflowTag, ApplicationsPhaseTag) + + def process(self): + for cfg in self.consume(KnownHostsProxyConfig): + sssdupdate.update_config(cfg) diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdupdate/libraries/sssdupdate.py b/repos/system_upgrade/el9toel10/actors/sssd/sssdupdate/libraries/sssdupdate.py new file mode 100644 index 00000000..6d745ead --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdupdate/libraries/sssdupdate.py @@ -0,0 +1,81 @@ +import os +import re + +from leapp.exceptions import StopActorExecutionError + + +def _process_knownhosts(line: str) -> str: + if re.search(r'^\s*#?\s*ProxyCommand\s+(/usr/bin/)?sss_ssh_knownhostsproxy', line) is not None: + # Update the line, leaving intact any # and any --domain/-d parameter + line = line.replace('ProxyCommand', 'KnownHostsCommand') + line = line.replace('sss_ssh_knownhostsproxy', 'sss_ssh_knownhosts') + line = line.replace('--port=', '') + line = line.replace('--port', '') + line = line.replace('-p=', '') + line = line.replace('-p', '') + line = line.replace('%p', '') + line = line.replace('%h', '%H') + + return line + + +def _process_enable_svc(line: str) -> str: + if re.search(r'^\s*#?\s*services\s*=', line) is not None: + if re.search(r'=\s*(.+,)?\s*ssh\s*(,.+)?\s*$', line) is None: + line = line.rstrip() + line += (',' if line[-1] != '=' else '') + 'ssh\n' + + return line + + +def _update_file(filename, process_function): + newname = filename + '.new' + oldname = filename + '.old' + try: + with open(filename, 'r') as input_file, open(newname, 'x') as output_file: + istat = os.fstat(input_file.fileno()) + os.fchmod(output_file.fileno(), istat.st_mode) + for line in input_file: + try: + output_file.write(process_function(line)) + except OSError as e: + raise StopActorExecutionError('Failed to write to {}'.format(newname), + details={'details': str(e)}) + + except FileExistsError as e: + raise StopActorExecutionError('Temporary file already exists: {}'.format(newname), + details={'details': str(e)}) + except OSError as e: + try: + os.unlink(newname) + except FileNotFoundError: + pass + raise StopActorExecutionError('Failed to access the required files', details={'details': str(e)}) + + # Let's make sure the old configuration is preserverd if something goes wrong + os.replace(filename, oldname) + os.replace(newname, filename) + os.unlink(oldname) + + +def _update_ssh_config(filename: str): + _update_file(filename, _process_knownhosts) + + +def _enable_svc(filename): + _update_file(filename, _process_enable_svc) + + +def update_config(model): + if not model: + return + + # If sss_ssh_knownhostsproxy was not configured, there is nothing to do + if not model.ssh_config_files: + return + + for file in model.ssh_config_files: + _update_ssh_config(file) + + for file in model.sssd_config_files: + _enable_svc(file) diff --git a/repos/system_upgrade/el9toel10/actors/sssd/sssdupdate/tests/unit_test_sssdupdate.py b/repos/system_upgrade/el9toel10/actors/sssd/sssdupdate/tests/unit_test_sssdupdate.py new file mode 100644 index 00000000..81414838 --- /dev/null +++ b/repos/system_upgrade/el9toel10/actors/sssd/sssdupdate/tests/unit_test_sssdupdate.py @@ -0,0 +1,273 @@ +import os +import random + +import pytest + +from leapp.libraries.actor import sssdupdate +from leapp.models import KnownHostsProxyConfig + + +class MockedFile: + """ + Mocks a file to avoid writing to the filesystem. + + This is the minimum mocking required for this test. + Most of the file functions are not implemented. + Only those required by this test. + """ + def __init__(self, name: str, fs): + self.name = name + self.fs = fs + self.fd = -1 + self.mode = 0o644 + self.contents = '' + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + return False + + def open(self, fd: int, mode: str): + self.fd = fd + if mode in ['w', 'x']: + self.contents = '' + + def fileno(self): + return self.fd + + def write(self, text: str) -> int: + self.contents += text + return len(text) + + def __iter__(self): + return iter(self.contents.splitlines(keepends=True)) + + def close(self): + self.fs._close(self.fd) + self.fd = -1 + + +class MockedStatResults: + def __init__(self, mode): + self.st_mode = mode + + +class MockedFileSystem: + """ + Mocks a filesystem. + + Simulates the minimum services needed by the tests in this file. + """ + def __init__(self): + self._by_name = {} + self._by_fd = [] + + def _get_by_fd(self, fd: int) -> MockedFile: + try: + return self._by_fd[fd] + except IndexError: + raise OSError('Bad file descriptor') + + def _get_by_name(self, name: str) -> MockedFile: + try: + return self._by_name[name] + except KeyError: + raise FileNotFoundError(name) + + def fstat(self, fd: int) -> MockedStatResults: + return MockedStatResults(self._get_by_fd(fd).mode) + + def fchmod(self, fd: int, mode: int): + file = self._get_by_fd(fd) + file.mode = mode + + def replace(self, src: str, dest: str): + file = self._get_by_name(src) + self._by_name[dest] = file + + def unlink(self, name: str): + del self._by_name[name] + + def open(self, name: str, mode: str) -> MockedFile: + if name not in self._by_name: + file = MockedFile(name, self) + self._by_name[name] = file + else: + if mode == 'x': + raise FileExistsError('File exists: ' + name) + file = self._by_name[name] + + self._by_fd.append(file) + fd = len(self._by_fd) - 1 + file.open(fd, mode) + + return file + + def _close(self, fd: int): + # This function is called by MockedFile.close() + self._by_fd[fd] = None + + +mocked_filesystem = MockedFileSystem() + + +@pytest.fixture(autouse=True) +def mock_filesystem(monkeypatch): + def mocked_open(name, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None): + return mocked_filesystem.open(name, mode) + + def mocked_fchmod(fd: int, mode: int): + mocked_filesystem.fchmod(fd, mode) + + def mocked_fstat(fd: int) -> MockedStatResults: + return mocked_filesystem.fstat(fd) + + def mocked_replace(src: str, dest: str): + mocked_filesystem.replace(src, dest) + + def mocked_unlink(name: str): + mocked_filesystem.unlink(name) + + monkeypatch.setattr("builtins.open", mocked_open) + monkeypatch.setattr(os, "fchmod", mocked_fchmod) + monkeypatch.setattr(os, "fstat", mocked_fstat) + monkeypatch.setattr(os, "replace", mocked_replace) + monkeypatch.setattr(os, "unlink", mocked_unlink) + + +def make_mock_file(contents: str) -> str: + name = os.path.join('/tmp', f'file.{str(random.uniform(1, 999999))}') + with mocked_filesystem.open(name, 'w') as file: + file.write(contents) + + return name + + +def make_files(contents: list[str]) -> list[str]: + files = [] + for conts in contents: + files.append(make_mock_file(conts)) + + return files + + +def check_file(name: str, expected: str): + assert name in mocked_filesystem._by_name.keys() # False positive => pylint: disable=consider-iterating-dictionary + assert mocked_filesystem._by_name[name].contents == expected + + +@pytest.mark.parametrize('sssd', [True, False]) +def test_sssdupdate__no_change(monkeypatch, sssd: bool): + contents = [ + """ + XXXXX XXXXXXXXX XXXXXXXXXXXX XXXXXXXXX + YYYYYYYY YYYYYY YYYYYYY YYYYYYYYYY + ZZZZZZ ZZZZZZZ ZZZZZZZ ZZZZZZZ ZZZZZZZ + AAAAAAA AAAAAAAAAA AAAAA + BBBBBBBB BBBBBBBBBB BBBBBBB BBBBB + CCCCCCCC CCCCCCC CCCCCCCC CCCCCCC + """, + """ + xxxxxx xxxxxxxxx xxxxxxxxx + yyyyyyyyy yyyyyyyyy yyyyyyyyyyyyyy + zzzzz zzzzzzz zzzzzzzzzzzz zzz + aaaaaa aaaaaaaa aaaaaaaaa aaaaaaaa + bbbbbbbb bbbbbbbbbb bbbbbbbb + """ + ] + + files = make_files(contents) + if sssd: + config = KnownHostsProxyConfig(sssd_config_files=files) + else: + config = KnownHostsProxyConfig(ssh_config_files=files) + + sssdupdate.update_config(config) + + for i in range(len(contents)): + check_file(files[i], contents[i]) + + +def test_sssdupdate__sssd_change(monkeypatch): + contents = [ + """ + [sssd] + services = pam, nss + domains = test + """, + """ + [sssd] + # services = pam,nss + domains = test + """, + """ + [sssd] + services = pam,ssh,nss + domains = test + """ + ] + expected = [ + """ + [sssd] + services = pam, nss,ssh + domains = test + """, + """ + [sssd] + # services = pam,nss,ssh + domains = test + """, + """ + [sssd] + services = pam,ssh,nss + domains = test + """ + ] + # A failure here indicates an error in the test + assert len(contents) == len(expected) + + sssd_files = make_files(contents) + ssh_files = make_files(['']) + config = KnownHostsProxyConfig(sssd_config_files=sssd_files, ssh_config_files=ssh_files) + + sssdupdate.update_config(config) + + for i in range(len(expected)): + check_file(sssd_files[i], expected[i]) + + +def test_sssdupdate__ssh_change(monkeypatch): + contents = [ + """ + First line + ProxyCommand /usr/bin/sss_ssh_knownhostsproxy -p %p -d domain %h + 3rd line + """, + """ + #\tProxyCommand /usr/bin/sss_ssh_knownhostsproxy --port=%p %h + # Another comment + """ + ] + expected = [ + """ + First line + KnownHostsCommand /usr/bin/sss_ssh_knownhosts -d domain %H + 3rd line + """, + """ + #\tKnownHostsCommand /usr/bin/sss_ssh_knownhosts %H + # Another comment + """ + ] + # A failure here indicates an error in the test + assert len(contents) == len(expected) + + files = make_files(contents) + config = KnownHostsProxyConfig(ssh_config_files=files) + + sssdupdate.update_config(config) + + for i in range(len(expected)): + check_file(files[i], expected[i]) diff --git a/repos/system_upgrade/el9toel10/models/sssd_knownhostsproxy.py b/repos/system_upgrade/el9toel10/models/sssd_knownhostsproxy.py new file mode 100644 index 00000000..4d2198fd --- /dev/null +++ b/repos/system_upgrade/el9toel10/models/sssd_knownhostsproxy.py @@ -0,0 +1,21 @@ +from leapp.models import fields, Model +from leapp.topics import SystemInfoTopic + + +class KnownHostsProxyConfig(Model): + """ + SSSD and SSH configuration that is related to the sss_ssh_knownhostsproxy tool. + """ + topic = SystemInfoTopic + + sssd_config_files = fields.List(fields.String(), default=[]) + """ + List of files in the sssd configuration that include `service` + and that may need to be updated. + """ + + ssh_config_files = fields.List(fields.String(), default=[]) + """ + List of files in the ssh configuration that include `sss_ssh_knownhostsproxy` + and that need to be updated. + """