@@ -95,11 +95,18 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
9595 parser .add_argument (
9696 "--operator" ,
9797 help = "Patch operator version in release.yaml. Format <operator>=<version>" ,
98- nargs = "* " ,
98+ action = "append " ,
9999 type = cli_parse_operator_args ,
100100 default = [],
101101 )
102102
103+ parser .add_argument (
104+ "--skip-operator" ,
105+ help = "Skip given operator(s) when installing a release." ,
106+ action = "append" ,
107+ default = [],
108+ )
109+
103110 parser .add_argument (
104111 "--test" ,
105112 help = "Kuttl test to run." ,
@@ -138,7 +145,7 @@ def cli_parse_operator_args(args: str) -> tuple[str, str]:
138145 f"Invalid operator argument: { args } . Must be in format <operator>=<version>"
139146 )
140147 op , version = args .split ("=" , maxsplit = 1 )
141- return ( op , version )
148+ return op , version
142149
143150
144151def cli_log_level (cli_arg : str ) -> int :
@@ -179,11 +186,13 @@ def have_requirements() -> None:
179186
180187@contextlib .contextmanager
181188def release_file (
182- operators : list [tuple [str , str ]] = [],
189+ operators : list [tuple [str , str ]], skip_ops : list [ str ]
183190) -> collections .abc .Generator [str , None , None ]:
184- """Patch release.yaml with operator versions if needed .
191+ """Generate a (possibly modified) copy of the release.yaml file .
185192
186- If no --operator is set, the default release file is used.
193+ Operator versions passed as --operator take precedence over the release.yaml contents.
194+
195+ Operators passed as --skip-operator are excluded from the resulting release.yaml contents.
187196
188197 If an invalid operator name is provided (i.e. one that doesn't exist in the
189198 original release file), a TestRunnerException is raised.
@@ -194,36 +203,61 @@ def release_file(
194203
195204 def _patch ():
196205 release_file = os .path .join ("tests" , "release.yaml" )
197- # Make a copy so we can mutate it without affecting the original
198- ops_copy = operators .copy ()
206+ # A marker to validate that all ops were patched
199207 patched_release = []
200208 with open (release_file , "r" ) as f :
209+ patched_ops = []
201210 patch_version = ""
202211 for line in f :
203212 if patch_version :
204213 line = re .sub (":.+$" , f": { patch_version } " , line )
205214 patch_version = ""
206215 else :
207- for op , version in ops_copy :
216+ for op , version in operators :
208217 if op in line :
209218 patch_version = version
210- ops_copy . remove (( op , version )) # found an operator to patch
219+ patched_ops . append ( op )
211220 break
212- patched_release .append (line )
213- if ops_copy :
214- # Some --operator args were not found in the release file. This is
215- # most likely a typo and CI pipelines should terminate early in such
216- # cases.
221+ patched_release .append (line .rstrip ("\n " ))
222+
223+ # Sanity test that cli didn't contain garbage that is silently discarded
224+ ops_not_patched = set ([op for op , _ in operators ]) - set (patched_ops )
225+ if ops_not_patched :
226+ logging .error (
227+ f"Patched operators [{ ', ' .join (ops_not_patched )} ] not found in { release_file } "
228+ )
229+ raise TestRunnerException ()
230+
231+ # Filter out skip operators
232+ release_contents = []
233+ skip_lines = 0
234+ valid_skip_ops = []
235+ for line in patched_release :
236+ if skip_lines :
237+ skip_lines -= 1
238+ continue
239+ for op in skip_ops :
240+ if op in line :
241+ # Every product section has 1 line of additional config to skip
242+ skip_lines = 1
243+ valid_skip_ops .append (op )
244+ break
245+ else :
246+ release_contents .append (line )
247+ # Sanity test that cli didn't contain garbage that is silently discarded
248+ ops_not_skipped = set (skip_ops ) - set (valid_skip_ops )
249+ if ops_not_skipped :
217250 logging .error (
218- f"Operators { ', ' .join ([ op for op , _ in ops_copy ]) } not found in { release_file } "
251+ f"Skipped operators [ { ', ' .join (ops_not_skipped ) } ] not found in { release_file } "
219252 )
220253 raise TestRunnerException ()
254+
221255 with tempfile .NamedTemporaryFile (
222256 mode = "w" ,
223257 delete = False ,
224258 prefix = "patched" ,
225259 ) as f :
226- pcontents = "" .join (patched_release )
260+ pcontents = "\n " .join (release_contents )
227261 logging .debug (f"Writing patched release to { f .name } : { pcontents } \n " )
228262 f .write (pcontents )
229263 return f .name
@@ -353,7 +387,7 @@ def main(argv) -> int:
353387 logging .basicConfig (encoding = "utf-8" , level = opts .log_level )
354388 have_requirements ()
355389 gen_tests (opts .test_suite )
356- with release_file (opts .operator ) as f :
390+ with release_file (opts .operator , opts . skip_operator ) as f :
357391 maybe_install_release (opts .skip_release , f )
358392 if opts .skip_tests :
359393 logging .info ("Skip running tests." )
0 commit comments