@@ -106,8 +106,10 @@ def remote_extra_fields(self, upstream_distribution):
106106 return {}
107107
108108 def create_or_update_remote (self , upstream_distribution ):
109- if not upstream_distribution .get ("repository" ) and not upstream_distribution .get (
110- "publication"
109+ if (
110+ not upstream_distribution .get ("repository" )
111+ and not upstream_distribution .get ("repository_version" )
112+ and not upstream_distribution .get ("publication" )
111113 ):
112114 return None
113115 url = self .url (upstream_distribution )
@@ -171,9 +173,18 @@ def create_or_update_repository(self, remote):
171173 def distribution_extra_fields (self , repository , upstream_distribution ):
172174 """
173175 Return the fields that need to be updated/cleared on distributions for idempotence.
176+
177+ Note: repository_version is computed here but filtered out for updates/creates.
178+ It will be set atomically in finalize_replication after sync completes.
174179 """
180+ latest = repository .latest_version ()
181+ if latest :
182+ repo_version_href = get_url (repository ) + "versions/{}/" .format (latest .number )
183+ else :
184+ repo_version_href = None
175185 return {
176- "repository" : get_url (repository ),
186+ "repository" : None ,
187+ "repository_version" : repo_version_href ,
177188 "publication" : None ,
178189 "base_path" : upstream_distribution ["base_path" ],
179190 }
@@ -187,7 +198,11 @@ def create_or_update_distribution(self, repository, upstream_distribution):
187198 )
188199 if not self ._is_managed (distro ):
189200 return None
190- needs_update = self .needs_update (distribution_data , distro )
201+ # Don't update repository_version here — that happens atomically in
202+ # finalize_replication after all syncs complete.
203+ # Do clear repository and publication so they don't conflict.
204+ update_data = {k : v for k , v in distribution_data .items () if k != "repository_version" }
205+ needs_update = self .needs_update (update_data , distro )
191206 if needs_update :
192207 # Update the distribution
193208 dispatch (
@@ -197,20 +212,28 @@ def create_or_update_distribution(self, repository, upstream_distribution):
197212 exclusive_resources = self .distros_uris ,
198213 args = (distro .pk , self .app_label , self .distribution_serializer_name ),
199214 kwargs = {
200- "data" : distribution_data ,
215+ "data" : update_data ,
201216 "partial" : True ,
202217 },
203218 )
204219 except self .distribution_model_cls .DoesNotExist :
205220 # Dispatch a task to create the distribution
206- distribution_data ["name" ] = upstream_distribution ["name" ]
221+ # Don't set repository_version for new distributions - it will be set in
222+ # finalize_replication after sync completes.
223+ create_data = {
224+ k : v
225+ for k , v in distribution_data .items ()
226+ if k not in ("repository_version" , "repository" , "publication" )
227+ }
228+ create_data ["name" ] = upstream_distribution ["name" ]
229+ create_data ["pulp_labels" ] = distribution_data ["pulp_labels" ]
207230 dispatch (
208231 general_create ,
209232 task_group = self .task_group ,
210233 shared_resources = [repository , self .server ],
211234 exclusive_resources = self .distros_uris ,
212235 args = (self .app_label , self .distribution_serializer_name ),
213- kwargs = {"data" : distribution_data },
236+ kwargs = {"data" : create_data },
214237 )
215238
216239 def sync_params (self , repository , remote ):
0 commit comments