Nested conditions are wrongly getting unnested
See original GitHub issue/kind bug
What steps did you take and what happened: A modified flip coin example in three variants to compare the results:
def flipcoin1(forced_result1: str = 'heads', forced_result2: str = 'heads'):
flip1 = FlipCoinOp('flip1', str(forced_result1))
flip2 = FlipCoinOp('flip2', str(forced_result2))
with dsl.Condition(flip1.output == 'heads'):
PrintOp('print', "{} {}".format(flip1.output, flip2.output))
def flipcoin2(forced_result1: str = 'heads', forced_result2: str = 'heads'):
flip1 = FlipCoinOp('flip1', str(forced_result1))
flip2 = FlipCoinOp('flip2', str(forced_result2))
with dsl.Condition(flip1.output == 'heads'):
with dsl.Condition(flip2.output == 'heads'):
PrintOp('print', "{} {}".format(flip1.output, flip2.output))
def flipcoin3(forced_result1: str = 'heads', forced_result2: str = 'heads'):
flip1 = FlipCoinOp('flip1', str(forced_result1))
flip2 = FlipCoinOp('flip2', str(forced_result2))
with dsl.Condition(flip1.output == 'heads'):
PrintOp('print-debug', "debug!")
with dsl.Condition(flip2.output == 'heads'):
PrintOp('print', "{} {}".format(flip1.output, flip2.output))
For Argo target, it looks as expected:
|- flip-coin-example-pipeline
|- flip1
|- flip2
|- condition-1 (deps: flip1, flip2), when flip1.output == "heads"
|- print
condition2.py
|- flip-coin-example-pipeline
|- flip1
|- flip2
|- condition-1 (deps: flip1, flip2), when flip1.output == "heads"
|- condition-2, when flip2.output == "heads"
|- print
condition3.py
|- flip-coin-example-pipeline
|- flip1
|- flip2
|- condition-1 (deps: flip1, flip2), when flip1.output == "heads"
|- debug-print
|- condition-2, when flip2.output == "heads"
|- print
For Tekton backend, though, the following is happening:
condition1.py
|- flip-coin-example-pipeline
|- flip1
|- flip2
|- condition-1: flip1.output == "heads"
|- print, when condition-1.status in "true"
condition2.py
|- flip-coin-example-pipeline
|- flip1
|- flip2
|- condition-1: flip1.output == "heads"
|- condition-2: flip2.output == "heads"
|- print, when condition-2.status in "true"
condition3.py
|- flip-coin-example-pipeline
|- flip1
|- flip2
|- condition-1: flip1.output == "heads"
|- print-debug, when condition-1.status in "true"
|- condition-2: flip2.output == "heads"
|- print, when condition-2.status in "true"
What did you expect to happen:
condition1.py looks fine to me
condition2.py looks like condition-1 is simply ignored instead of making a chain of dependency. I’d expect it to be sth like (it should be possible, now that the conditions’ templates aren’t limited to a single super-condition
resource):
condition2.py
|- flip-coin-example-pipeline
|- flip1
|- flip2
|- condition-1: flip1.output == "heads"
|- condition-2: flip2.output == "heads", when condition-1.status in "true"
|- print, when condition-2.status in "true"
condition3.py looks like condition-1 is only applied to ContainerOps that are directly under it with no other group in-between, thus making the two conditions independent of each other. I’d expect it looked like that instead:
condition3.py
|- flip-coin-example-pipeline
|- flip1
|- flip2
|- condition-1: flip1.output == "heads"
|- print-debug, when condition-1.status is "true"
|- condition-2: flip2.output == "heads", when condition-1.status in "true"
|- print, when condition-2.status in "true"
Both condition2.py and condition3.py look like conditions are simply factored out of any nesting:
def flipcoin2(forced_result1: str = 'heads', forced_result2: str = 'heads'):
flip1 = FlipCoinOp('flip1', str(forced_result1))
flip2 = FlipCoinOp('flip2', str(forced_result2))
with dsl.Condition(flip1.output == 'heads'):
pass
with dsl.Condition(flip2.output == 'heads'):
PrintOp('print', "{} {}".format(flip1.output, flip2.output))
def flipcoin3(forced_result1: str = 'heads', forced_result2: str = 'heads'):
flip1 = FlipCoinOp('flip1', str(forced_result1))
flip2 = FlipCoinOp('flip2', str(forced_result2))
with dsl.Condition(flip1.output == 'heads'):
PrintOp('print-debug', "debug!")
with dsl.Condition(flip2.output == 'heads'):
PrintOp('print', "{} {}".format(flip1.output, flip2.output))
Additional information:
It looks like only tasks get the when
at all, as I can only see it in looping over task_refs
directly in _create_pipeline_workflow
:
# add task dependencies and add condition refs to the task ref that depends on the condition
op_name_to_parent_groups = self._get_groups_for_ops(pipeline.groups[0])
for task in task_refs:
op = pipeline.ops.get(task['name'])
parent_group = op_name_to_parent_groups.get(task['name'], [])
if parent_group:
if condition_refs.get(parent_group[-2], []):
task['when'] = condition_refs.get(op_name_to_parent_groups[task['name']][-2], [])
Environment:
- Python Version (use
python --version
): 3.9.0 (although it should be irrelevant) - SDK Version: 0.5.0
- Tekton Version (use
tkn version
): - Kubernetes Version (use
kubectl version
): - OS (e.g. from
/etc/os-release
):
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (6 by maintainers)
Top GitHub Comments
Thanks @Udiknedormin, I just came back from the holidays. I will try to address it in our SDK.
Great, that is exactly how I imagined it to be working, seems to cover all of the use-cases. Thank you!