Skip to content

Commit 928a71d

Browse files
authored
Fix for rhel subscription always mode cache to disable by default (#4866)
Signed-off-by: pullan1 <sudha.pullalaravu@dell.com>
1 parent 26165c0 commit 928a71d

4 files changed

Lines changed: 114 additions & 127 deletions

File tree

common/library/module_utils/local_repo/software_utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ def parse_repo_urls(repo_config, local_repo_config_path,
399399
client_key = url_.get("sslclientkey", "")
400400
client_cert = url_.get("sslclientcert", "")
401401
policy_given = url_.get("policy", repo_config)
402-
caching_given = url_.get("caching", True)
402+
caching_given = url_.get("caching", repo_config != "always")
403403
policy = resolve_pulp_policy(
404404
policy_given, caching_given, logger
405405
)
@@ -444,7 +444,7 @@ def parse_repo_urls(repo_config, local_repo_config_path,
444444
client_key = url_.get("sslclientkey", "")
445445
client_cert = url_.get("sslclientcert", "")
446446
policy_given = url_.get("policy", repo_config)
447-
caching_given = url_.get("caching", True)
447+
caching_given = url_.get("caching", repo_config != "always")
448448
policy = resolve_pulp_policy(
449449
policy_given, caching_given, logger
450450
)
@@ -497,7 +497,7 @@ def parse_repo_urls(repo_config, local_repo_config_path,
497497
url = repo.get("url", "")
498498
gpgkey = repo.get("gpgkey", "")
499499
policy_given = repo.get("policy", repo_config)
500-
caching_given = repo.get("caching", True)
500+
caching_given = repo.get("caching", repo_config != "always")
501501
policy = resolve_pulp_policy(
502502
policy_given, caching_given, logger
503503
)

common/library/modules/process_rpm_config.py

Lines changed: 71 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -865,10 +865,18 @@ def process_sync_results(sync_results, rpm_config, resync_repos, log):
865865
"""
866866
Process sync results and determine which repos need publication/distribution.
867867
868+
This function handles two scenarios:
869+
1. Repos with version changes from current sync - need new publication/distribution
870+
2. Repos that were synced previously but missing publication/distribution (crash recovery)
871+
- This check is performed for ALL repos regardless of resync_repos setting
872+
- Ensures that if a previous run synced repos A, B, C but failed before creating
873+
pub/dist, a subsequent run (even with resync_repos=["D"]) will still create
874+
the missing pub/dist for A, B, C
875+
868876
Args:
869877
sync_results (list): Results from sync_rpm_repository (success, name, actually_synced, version_changed).
870878
rpm_config (list): List of repository configurations.
871-
resync_repos (str/list): Controls which repos to process.
879+
resync_repos (str/list): Controls which repos to sync (not which repos to check for pub/dist).
872880
log (logging.Logger): Logger instance.
873881
874882
Returns:
@@ -882,112 +890,72 @@ def process_sync_results(sync_results, rpm_config, resync_repos, log):
882890
version_changed_repos = [name for success, name, actually_synced, version_changed in sync_results if success and actually_synced and version_changed]
883891
log.info(f"Repos with version change: {len(version_changed_repos)} - {version_changed_repos}")
884892

885-
# If no versions changed, check for missing publication/distribution
886-
# This handles the crash recovery case: process failed after sync but before pub/dist
887-
if not version_changed_repos:
888-
log.info("No version changes detected. Checking for missing publication/distribution.")
889-
890-
# Check all synced repos (including previously synced) for missing pub/dist
891-
repos_missing_pub_dist = []
892-
all_repo_names = []
893-
for repo in rpm_config:
894-
repo_name = repo["package"]
895-
version = repo.get("version")
896-
if version and version != "null":
897-
repo_name = f"{repo_name}_{version}"
898-
all_repo_names.append(repo_name)
899-
900-
# If resync_repos is a specific list, only check those repos
901-
if resync_repos and resync_repos != "all":
902-
resync_list = resync_repos if isinstance(resync_repos, list) else [r.strip() for r in resync_repos.split(",")]
903-
if repo_name not in resync_list:
904-
continue
905-
906-
pub_exists = check_publication_exists(repo_name, log)
907-
dist_exists = check_distribution_exists(repo_name, log)
908-
909-
if not pub_exists or not dist_exists:
910-
log.info(f"{repo_name} missing publication={not pub_exists}, distribution={not dist_exists}. Including for pub/dist creation.")
911-
repo_copy = repo.copy()
912-
repo_copy["_version_changed"] = False
913-
repos_missing_pub_dist.append(repo_copy)
914-
915-
if repos_missing_pub_dist:
916-
missing_names = [r["package"] for r in repos_missing_pub_dist]
917-
log.info(f"Found {len(repos_missing_pub_dist)} repo(s) missing publication/distribution: {missing_names}")
918-
return repos_missing_pub_dist, False, ""
919-
920-
# All repos have publication and distribution - safe to skip
921-
log.info("All repos have existing publication and distribution. Skipping.")
922-
if actually_synced_repos:
923-
# Repos were synced but no metadata change
924-
synced_list = ", ".join(actually_synced_repos)
925-
skip_msg = f"Sync successful for {len(actually_synced_repos)} repo(s): {synced_list}. No metadata changes detected - existing publication/distribution retained"
926-
else:
927-
# No repos were synced at all (already up to date)
928-
skip_msg = "All repositories already synced - no updates required"
929-
return [], True, skip_msg
930-
931893
repos_for_pub_dist = []
894+
repos_for_pub_dist_names = set() # Track names to avoid duplicates
932895

933-
if resync_repos == "all":
934-
log.info("resync_repos='all' - Processing publication and distribution for repos with version change")
935-
for repo in rpm_config:
936-
repo_name = repo["package"]
937-
version = repo.get("version")
938-
if version and version != "null":
939-
repo_name = f"{repo_name}_{version}"
940-
# Only include repos with version change
941-
if repo_name in version_changed_repos:
942-
repo_copy = repo.copy()
943-
repo_copy["_version_changed"] = True
944-
repos_for_pub_dist.append(repo_copy)
896+
# Step 1: Add repos with version changes (these definitely need new publication)
897+
for repo in rpm_config:
898+
repo_name = repo["package"]
899+
version = repo.get("version")
900+
if version and version != "null":
901+
repo_name = f"{repo_name}_{version}"
902+
903+
if repo_name in version_changed_repos:
904+
repo_copy = repo.copy()
905+
repo_copy["_version_changed"] = True
906+
repos_for_pub_dist.append(repo_copy)
907+
repos_for_pub_dist_names.add(repo_name)
908+
log.info(f"{repo_name} has version change. Including for pub/dist creation.")
909+
910+
# Step 2: Check ALL repos for missing publication/distribution (crash recovery)
911+
# This is independent of resync_repos - we always want to ensure all synced repos
912+
# have their publication/distribution created
913+
log.info("Checking all repos for missing publication/distribution (crash recovery check).")
914+
915+
for repo in rpm_config:
916+
repo_name = repo["package"]
917+
version = repo.get("version")
918+
if version and version != "null":
919+
repo_name = f"{repo_name}_{version}"
920+
921+
# Skip if already added due to version change
922+
if repo_name in repos_for_pub_dist_names:
923+
continue
924+
925+
# Check if repo is synced (has content) but missing publication or distribution
926+
# First verify the repo has been synced at least once (version > 0)
927+
repo_version = get_repo_version(repo_name, log)
928+
if repo_version == 0:
929+
# Repo has never been synced, skip it
930+
log.debug(f"{repo_name} has never been synced (version=0). Skipping pub/dist check.")
931+
continue
932+
933+
pub_exists = check_publication_exists(repo_name, log)
934+
dist_exists = check_distribution_exists(repo_name, log)
935+
936+
if not pub_exists or not dist_exists:
937+
log.info(f"{repo_name} is synced (version={repo_version}) but missing publication={not pub_exists}, distribution={not dist_exists}. Including for pub/dist creation.")
938+
repo_copy = repo.copy()
939+
repo_copy["_version_changed"] = False # No version change, just missing pub/dist
940+
repos_for_pub_dist.append(repo_copy)
941+
repos_for_pub_dist_names.add(repo_name)
942+
943+
# Determine if we should skip or process
944+
if repos_for_pub_dist:
945+
pub_dist_names = [r["package"] for r in repos_for_pub_dist]
946+
log.info(f"Found {len(repos_for_pub_dist)} repo(s) needing publication/distribution: {pub_dist_names}")
945947
return repos_for_pub_dist, False, ""
948+
949+
# All repos have publication and distribution - safe to skip
950+
log.info("All synced repos have existing publication and distribution. Skipping pub/dist creation.")
951+
if actually_synced_repos:
952+
# Repos were synced but no metadata change
953+
synced_list = ", ".join(actually_synced_repos)
954+
skip_msg = f"Sync successful for {len(actually_synced_repos)} repo(s): {synced_list}. No metadata changes detected - existing publication/distribution retained"
946955
else:
947-
# If no repos were actually synced, check for missing pub/dist (crash recovery)
948-
if not actually_synced_repos:
949-
log.info("No repos were actually synced. Checking for missing publication/distribution.")
950-
repos_missing_pub_dist = []
951-
for repo in rpm_config:
952-
repo_name = repo["package"]
953-
version = repo.get("version")
954-
if version and version != "null":
955-
repo_name = f"{repo_name}_{version}"
956-
957-
# If resync_repos is a specific list, only check those repos
958-
if resync_repos and resync_repos != "all":
959-
resync_list = resync_repos if isinstance(resync_repos, list) else [r.strip() for r in resync_repos.split(",")]
960-
if repo_name not in resync_list:
961-
continue
962-
963-
pub_exists = check_publication_exists(repo_name, log)
964-
dist_exists = check_distribution_exists(repo_name, log)
965-
966-
if not pub_exists or not dist_exists:
967-
log.info(f"{repo_name} missing publication={not pub_exists}, distribution={not dist_exists}. Including for pub/dist creation.")
968-
repo_copy = repo.copy()
969-
repo_copy["_version_changed"] = False
970-
repos_missing_pub_dist.append(repo_copy)
971-
972-
if repos_missing_pub_dist:
973-
missing_names = [r["package"] for r in repos_missing_pub_dist]
974-
log.info(f"Found {len(repos_missing_pub_dist)} repo(s) missing publication/distribution: {missing_names}")
975-
return repos_missing_pub_dist, False, ""
976-
977-
log.info("All repos have existing publication and distribution. No updates required.")
978-
return [], True, "All repositories already synced - no updates required"
979-
980-
# Filter rpm_config to only include repos with version change
981-
for repo in rpm_config:
982-
repo_name = repo["package"]
983-
version = repo.get("version")
984-
if version and version != "null":
985-
repo_name = f"{repo_name}_{version}"
986-
if repo_name in actually_synced_repos and repo_name in version_changed_repos:
987-
repo_copy = repo.copy()
988-
repo_copy["_version_changed"] = True
989-
repos_for_pub_dist.append(repo_copy)
990-
return repos_for_pub_dist, False, ""
956+
# No repos were synced at all (already up to date)
957+
skip_msg = "All repositories already synced - no updates required"
958+
return [], True, skip_msg
991959

992960
# ============================================================================
993961
# AGGREGATED REPOS FUNCTIONS

input/local_repo_config.yml

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,34 @@
1818
# ================================
1919
# VARIABLE DETAILS
2020
# ================================
21+
# IMPORTANT: Policy and Caching Behavior (applies to all repository configurations)
22+
#----------------------------------------------------------------------------------
23+
# The 'policy' and 'caching' fields control how Pulp downloads and stores packages:
24+
#
25+
# policy : Repository sync policy. Allowed values: always, partial (OPTIONAL)
26+
# If not provided, uses repo_config from software_config.json
27+
#
28+
# caching : Controls Pulp download behavior with policy. Allowed values: true, false (OPTIONAL)
29+
# If not provided, defaults based on repo_config:
30+
# - repo_config: always → caching defaults to false (Pulp 'immediate' policy)
31+
# - repo_config: partial → caching defaults to true (Pulp 'on_demand' policy)
32+
#
33+
# Policy + Caching Mapping to Pulp Download Policy:
34+
# ┌──────────┬──────────┬────────────────┬─────────────────────────────────────────────────┐
35+
# │ policy │ caching │ Pulp Policy │ Behavior │
36+
# ├──────────┼──────────┼────────────────┼─────────────────────────────────────────────────┤
37+
# │ always │ false │ immediate │ Packages downloaded and stored locally on OIM │
38+
# │ always │ true │ on_demand │ Packages fetched from upstream on demand │
39+
# │ partial │ true │ on_demand │ Packages fetched from upstream on demand │
40+
# │ partial │ false │ streamed │ Packages streamed on demand, not stored │
41+
# └──────────┴──────────┴────────────────┴─────────────────────────────────────────────────┘
42+
#
43+
# To achieve full local download (immediate): Set repo_config: always in software_config.json
44+
# OR set policy: always + caching: false per repo
45+
# To achieve proxy mode (on_demand): Set repo_config: partial
46+
# OR set policy: always + caching: true per repo
47+
#----------------------------------------------------------------------------------
48+
2149
# 1. user_registry
2250
#--------------------------
2351
# Configuration for user registry to configure additional images in Pulp
@@ -43,10 +71,8 @@
4371
# sslcacert : Path to SSL CA certificate (if using SSL)
4472
# sslclientkey: Path to SSL client key (if using SSL)
4573
# sslclientcert: Path to SSL client certificate (if using SSL)
46-
# policy : Repository sync policy. Allowed values: always, partial (OPTIONAL)
47-
# If not provided, uses repo_config from software_config.json
48-
# caching : Enable or disable local caching. Allowed values: true, false (OPTIONAL)
49-
# If not provided, defaults to true
74+
# policy : See 'Policy and Caching Behavior' section at top for details (OPTIONAL)
75+
# caching : See 'Policy and Caching Behavior' section at top for details (OPTIONAL)
5076
# Notes:
5177
# - Do not use Jinja variables in this configuration.
5278
# - Omit SSL fields entirely if SSL is not in use.
@@ -67,10 +93,8 @@
6793
# sslcacert : Path to SSL CA certificate (if using SSL)
6894
# sslclientkey: Path to SSL client key (if using SSL)
6995
# sslclientcert: Path to SSL client certificate (if using SSL)
70-
# policy : Repository policy if mentioned allowed values (always, partial).
71-
# If not provided, uses repo_config from software_config.json
72-
# caching : Enable or disable local caching. Allowed values: true, false (OPTIONAL)
73-
# If not provided, defaults to true
96+
# policy : See 'Policy and Caching Behavior' section at top for details (OPTIONAL)
97+
# caching : See 'Policy and Caching Behavior' section at top for details (OPTIONAL)
7498
# name : Name of the repository [ Allowed repo names: codeready-builder, appstream, baseos ]
7599
# Notes:
76100
# - Do not use Jinja variables in this configuration.
@@ -94,16 +118,15 @@
94118
# name : Repository name for matching (REQUIRED)
95119
# Use 'baseos', 'appstream', or 'codeready-builder' to override base repo URLs
96120
# gpgkey : GPG key URL (OPTIONAL, defaults to empty to disable gpgcheck)
97-
# policy : Repository sync policy. Allowed values: always, partial (OPTIONAL)
98-
# If not provided, uses repo_config from software_config.json
99-
# caching : Enable or disable local caching. Allowed values: true, false (OPTIONAL)
100-
# If not provided, defaults to true
121+
# policy : See 'Policy and Caching Behavior' section at top for details (OPTIONAL)
122+
# caching : See 'Policy and Caching Behavior' section at top for details (OPTIONAL)
101123
# Notes:
102124
# - Only 'url' and 'name' are required fields
103125
# - SSL certificates are ALWAYS auto-populated from RHEL subscription defaults
104126
# - User cannot override SSL certificates (sslcacert, sslclientkey, sslclientcert)
105127
# - Matching is done by repository name (e.g., baseos, appstream, codeready-builder)
106128
# - Non-matching repositories are added as additional repos with subscription certs
129+
# - When repo_config: always in software_config.json, subscription repos use 'immediate' by default
107130
#
108131
# 7. rhel_subscription_repo_config_aarch64
109132
#--------------------------------------------
@@ -122,10 +145,8 @@
122145
# gpgkey : URL of the GPG key for the repository.
123146
# If left empty, gpgcheck=0 for that repository.
124147
# name : A unique identifier for the repository or registry.
125-
# policy : Repository sync policy. Allowed values: always, partial (OPTIONAL)
126-
# If not provided, uses repo_config from software_config.json
127-
# caching : Enable or disable local caching. Allowed values: true, false (OPTIONAL)
128-
# If not provided, defaults to true
148+
# policy : See 'Policy and Caching Behavior' section at top for details (OPTIONAL)
149+
# caching : See 'Policy and Caching Behavior' section at top for details (OPTIONAL)
129150
# 9. omnia_repo_url_rhel_aarch64
130151
#--------------------------------
131152
# Same as above but for RHEL aarch64.
@@ -142,10 +163,8 @@
142163
# sslcacert : Path to SSL CA certificate (optional)
143164
# sslclientkey : Path to SSL client key (optional)
144165
# sslclientcert : Path to SSL client certificate (optional)
145-
# policy : Repository sync policy. Allowed values: always, partial (OPTIONAL)
146-
# If not provided, uses repo_config from software_config.json
147-
# caching : Enable or disable local caching. Allowed values: true, false (OPTIONAL)
148-
# If not provided, defaults to true
166+
# policy : See 'Policy and Caching Behavior' section at top for details (OPTIONAL)
167+
# caching : See 'Policy and Caching Behavior' section at top for details (OPTIONAL)
149168
# Notes:
150169
# - All repos are synced into a single aggregated Pulp repository
151170
# - Compute nodes are configured once with a fixed URL that never changes

input_validation/roles/validate_subscription/tasks/configure_rhel_os_urls.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
sub_rhel_x86_64_urls: []
8585
sub_rhel_aarch64_urls: []
8686
sub_policy_default: "{{ sw_config.repo_config | default('on_demand') }}"
87-
sub_caching_default: true
87+
sub_caching_default: "{{ false if (sw_config.repo_config | default('on_demand')) == 'always' else true }}"
8888
sub_x86_64_override_config: "{{ local_config.rhel_subscription_repo_config_x86_64 | default([]) }}"
8989
sub_aarch64_override_config: "{{ local_config.rhel_subscription_repo_config_aarch64 | default([]) }}"
9090

0 commit comments

Comments
 (0)