@@ -62,11 +62,6 @@ def get_cv(org_id, cleanup_list, keep):
6262
6363 return ver_list , ver_descr , ver_keep
6464
65- def get_content_view_version (cvid ):
66- cvv = helpers .get_json (
67- helpers .KATELLO_API + "content_view_versions/" + str (cvid ))
68-
69- return cvv
7065
7166def get_content_view_info (cvid ):
7267 """
@@ -78,6 +73,32 @@ def get_content_view_info(cvid):
7873 return cvinfo
7974
8075
76+ def check_version_views (version_id ):
77+ """
78+ Check if our version ID belongs to any views, including CCV
79+ """
80+ version_in_use = False
81+ version_in_ccv = False
82+
83+ # Extract a list of content views that the CV version belongs to
84+ viewlist = helpers .get_json (
85+ helpers .KATELLO_API + "content_view_versions/" + str (version_id ))
86+
87+ # If the list is not empty we need to return this fact. A CV that belongs
88+ # to NO versions will be a candidate for cleanup.
89+ viewlist ['composite_content_view_ids' ]
90+ if viewlist ['katello_content_views' ]:
91+ version_in_use = True
92+ msg = "Version " + str (viewlist ['version' ]) + " is associated with published CV"
93+ helpers .log_msg (msg , 'DEBUG' )
94+
95+ # We can go further and see if this is associated with a CCV
96+ if viewlist ['composite_content_view_ids' ]:
97+ version_in_ccv = True
98+
99+ return version_in_use , version_in_ccv
100+
101+
81102def cleanup (ver_list , ver_descr , dry_run , runuser , ver_keep , cleanall , ignorefirstpromoted ):
82103 """Clean Content Views"""
83104
@@ -95,23 +116,43 @@ def cleanup(ver_list, ver_descr, dry_run, runuser, ver_keep, cleanall, ignorefir
95116 sys .exit (1 )
96117
97118 for cvid in ver_list .keys ():
98- # Check if there is a publish/promote already running on this content view
99- locked = helpers .check_running_publish (ver_list [cvid ], ver_descr [cvid ])
100-
101- msg = "Cleaning content view '" + str (ver_descr [cvid ]) + "'"
119+ msg = "Cleaning content view '" + str (ver_descr [cvid ]) + "'"
102120 helpers .log_msg (msg , 'INFO' )
103121 print helpers .HEADER + msg + helpers .ENDC
104122
123+ # Check if there is a publish/promote already running on this content view
124+ locked = helpers .check_running_publish (ver_list [cvid ], ver_descr [cvid ])
125+ if locked :
126+ continue
127+
105128 # For the given content view we need to find the orphaned versions
106129 cvinfo = get_content_view_info (cvid )
107130
108131 # Find the oldest published version
109132 version_list = []
110- version_list_all = []
133+ orphan_versions = []
134+ orphan_dict = {}
135+ all_versions = []
136+ ccv_versions = []
111137 for version in cvinfo ['versions' ]:
138+
139+ # Check if the version is part of a published view.
140+ # This is not returned in cvinfo, and we need to see if we are part of a CCV
141+ version_in_use , version_in_ccv = check_version_views (version ['id' ])
142+
143+ # Build a list of ALL version numbers
144+ all_versions .append (float (version ['version' ]))
145+ # Add any version numbers that are part of a CCV to a list
146+ if version_in_ccv :
147+ ccv_versions .append (float (version ['version' ]))
112148 if not version ['environment_ids' ]:
113- version_list_all .append (float (version ['version' ]))
114- continue
149+ # These are the versions that don't belong to an environment (i.e. orphans)
150+ # We also cross-check for versions that may be in a CCV here.
151+ # We add the version name and id into a dictionary so we can delete by id.
152+ if not version_in_use :
153+ orphan_versions .append (float (version ['version' ]))
154+ orphan_dict [version ['version' ]] = version ['id' ]
155+ continue
115156 else :
116157 msg = "Found version " + str (version ['version' ])
117158 helpers .log_msg (msg , 'DEBUG' )
@@ -127,95 +168,101 @@ def cleanup(ver_list, ver_descr, dry_run, runuser, ver_keep, cleanall, ignorefir
127168 helpers .log_msg (msg , 'DEBUG' )
128169
129170 # Find the oldest 'NOT in use' version id
130- if not version_list_all :
171+ if not orphan_versions :
131172 msg = "No oldest NOT-in-use version found"
132173 else :
133- msg = "Oldest NOT-in-use version is " + str (min (version_list_all ))
174+ msg = "Oldest NOT-in-use version is " + str (min (orphan_versions ))
134175 helpers .log_msg (msg , 'DEBUG' )
135176
136- # Find version to delete (based on keep parameter) if --ignorefirstpromoted
137- version_list_all .sort ()
138- todelete = version_list_all [:(len (version_list_all ) - int (ver_keep [cvid ]))]
139- msg = "Versions to remove if --ignorefirstpromoted: " + str (todelete )
177+ # Find the element position in the all_versions list of the oldest in-use version
178+ # e.g. vers 102.0 is oldest in-use and is element [5] in the all_versions list
179+ list_position = [i for i ,x in enumerate (all_versions ) if x == lastver ]
180+ # Remove the number of views to keep from the element position of the oldest in-use
181+ # e.g. keep=2 results in an adjusted list element position [3]
182+ num_to_delete = list_position [0 ] - int (ver_keep [cvid ])
183+ # Delete from position [0] to the first 'keep' position
184+ # e.g. first keep element is [3] so list of elements [0, 1, 2] is created
185+ list_pos_to_delete = [i for i in range (num_to_delete )]
186+
187+ # Find versions to delete (based on keep parameter)
188+ # Make sure the version list is in order
189+ orphan_versions .sort ()
190+
191+ if cleanall :
192+ # Remove all orphaned versions
193+ todelete = orphan_versions
194+ elif ignorefirstpromoted :
195+ # Remove the last 'keep' elements from the orphans list (from PR #26)
196+ todelete = orphan_versions [:(len (orphan_versions ) - int (ver_keep [cvid ]))]
197+ else :
198+ todelete = []
199+ # Remove the element numbers for deletion from the list all versions
200+ for i in sorted (list_pos_to_delete , reverse = True ):
201+ todelete .append (orphan_versions [i ])
202+
203+ msg = "Versions to remove: " + str (todelete )
140204 helpers .log_msg (msg , 'DEBUG' )
141205
142- for version in cvinfo ['versions' ]:
143- # Get composite content views for version
144- cvv = get_content_view_version (version ['id' ])
145- # Find versions that are not in any environment and not in any composite content view
146- if not version ['environment_ids' ] and not cvv ['composite_content_view_ids' ]:
147- if not locked :
148- msg = "Orphan view version " + str (version ['version' ]) + " found in '" + \
206+ for version in all_versions :
207+ if not locked :
208+ if version in todelete :
209+ msg = "Orphan view version " + str (version ) + " found in '" + \
149210 str (ver_descr [cvid ]) + "'"
150211 helpers .log_msg (msg , 'DEBUG' )
151212
152- if ignorefirstpromoted :
153- if cleanall :
154- msg = "Removing version " + str (version ['version' ])
155- helpers .log_msg (msg , 'INFO' )
156- print helpers .HEADER + msg + helpers .ENDC
157- else :
158- if float (version ['version' ]) in todelete :
159- # If ignorefirstpromoted delete CV
160- msg = "Removing version " + str (version ['version' ])
161- helpers .log_msg (msg , 'INFO' )
162- print helpers .HEADER + msg + helpers .ENDC
163- else :
164- msg = "Skipping delete of version " + str (version ['version' ]) + " due to --keep value"
165- helpers .log_msg (msg , 'INFO' )
166- print msg
167- continue
213+ # Lookup the version_id from our orphan_dict
214+ delete_id = orphan_dict .get (str (version ))
215+
216+ msg = "Removing version " + str (version )
217+ helpers .log_msg (msg , 'INFO' )
218+ print helpers .HEADER + msg + helpers .ENDC
219+ else :
220+ if version in ccv_versions :
221+ msg = "Skipping delete of version " + str (version ) + " (member of a CCV)"
222+ elif version in orphan_versions :
223+ msg = "Skipping delete of version " + str (version ) + " (due to keep value)"
224+ else :
225+ msg = "Skipping delete of version " + str (version ) + " (in use)"
226+ helpers .log_msg (msg , 'INFO' )
227+ print msg
228+ continue
229+ else :
230+ msg = "Version " + str (version ) + " is locked"
231+ helpers .log_msg (msg , 'WARNING' )
232+ continue
233+
234+ # Delete the view version from the content view
235+ if not dry_run and not locked :
236+ try :
237+ task_id = helpers .put_json (
238+ helpers .KATELLO_API + "content_views/" + str (cvid ) + "/remove/" ,
239+ json .dumps (
240+ {
241+ "id" : cvid ,
242+ "content_view_version_ids" : delete_id
243+ }
244+ ))['id' ]
245+
246+ # Wait for the task to complete
247+ helpers .wait_for_task (task_id ,'clean' )
248+
249+ # Check if the deletion completed successfully
250+ tinfo = helpers .get_task_status (task_id )
251+ if tinfo ['state' ] != 'running' and tinfo ['result' ] == 'success' :
252+ msg = "Removal of content view version OK"
253+ helpers .log_msg (msg , 'INFO' )
254+ print helpers .GREEN + "OK" + helpers .ENDC
168255 else :
169- if float (version ['version' ]) > float (lastver ):
170- # If we have chosen to remove all orphans
171- if cleanall :
172- msg = "Removing version " + str (version ['version' ])
173- helpers .log_msg (msg , 'INFO' )
174- print helpers .HEADER + msg + helpers .ENDC
175- else :
176- msg = "Skipping delete of version " + str (version ['version' ])
177- helpers .log_msg (msg , 'INFO' )
178- print msg
179- continue
180- else :
181- if float (version ['version' ]) < (lastver - float (ver_keep [cvid ])):
182- msg = "Removing version " + str (version ['version' ])
183- helpers .log_msg (msg , 'INFO' )
184- print helpers .HEADER + msg + helpers .ENDC
185- else :
186- msg = "Skipping delete of version " + str (version ['version' ]) + " due to --keep value"
187- helpers .log_msg (msg , 'INFO' )
188- print msg
189- continue
190-
191- # Delete the view version from the content view
192- if not dry_run and not locked :
193- try :
194- task_id = helpers .put_json (
195- helpers .KATELLO_API + "content_views/" + str (cvid ) + "/remove/" ,
196- json .dumps (
197- {
198- "id" : cvid ,
199- "content_view_version_ids" : version ['id' ]
200- }
201- ))['id' ]
202-
203- # Wait for the task to complete
204- helpers .wait_for_task (task_id ,'clean' )
205-
206- # Check if the deletion completed successfully
207- tinfo = helpers .get_task_status (task_id )
208- if tinfo ['state' ] != 'running' and tinfo ['result' ] == 'success' :
209- msg = "Removal of content view version OK"
210- helpers .log_msg (msg , 'INFO' )
211- print helpers .GREEN + "OK" + helpers .ENDC
212- else :
213- msg = "Failed"
214- helpers .log_msg (msg , 'ERROR' )
215-
216- except Warning :
217- msg = "Failed to initiate removal"
218- helpers .log_msg (msg , 'WARNING' )
256+ msg = "Failed"
257+ helpers .log_msg (msg , 'ERROR' )
258+
259+ except Warning :
260+ msg = "Failed to initiate removal"
261+ helpers .log_msg (msg , 'WARNING' )
262+
263+ except KeyError :
264+ msg = "Failed to initiate removal (KeyError)"
265+ helpers .log_msg (msg , 'WARNING' )
219266
220267 # Exit in the case of a dry-run
221268 if dry_run :
@@ -299,5 +346,3 @@ def main(args):
299346 except KeyboardInterrupt , e :
300347 print >> sys .stderr , ("\n \n Exiting on user cancel." )
301348 sys .exit (1 )
302-
303-
0 commit comments