-
Notifications
You must be signed in to change notification settings - Fork 809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(pipelines): expectedArtifacts inheritance from dynamic parent templates #3023
Conversation
@spinnaker/reviewers |
...y/com/netflix/spinnaker/orca/pipelinetemplate/v1schema/V1SchemaExecutionGeneratorSpec.groovy
Show resolved
Hide resolved
...y/com/netflix/spinnaker/orca/pipelinetemplate/v1schema/V1SchemaExecutionGeneratorSpec.groovy
Show resolved
Hide resolved
// result.stages.size() == 1 | ||
// result.stages[0].type == "wait" | ||
// result.stages[0].refId == "wait1" | ||
// result.stages[0].name == "Wait for 5 seconds" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe remove these if not relevant anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
pipelineConfig = preprocessor.process(pipelineConfig) | ||
} | ||
|
||
pipelineConfig.trigger = trigger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason you are moving this back? It breaks what I fixed in #2963.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently it will be required to run resolve artifacts twice. I added a comment in code explaining why
@spinnaker/google-reviewers PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a few comments inline to try to understand this better. I'm a bit nervous about this change as there have been a lot of bugs in artifact resolution for pipeline templates recently, and this code is very fragile so I want to make sure that fixing this particular edge case doesn't introduce more general issues. If there's any way to scope the change more specifically to this change rather than always resolving twice, that might be preferable.
I'm less familiar with the V1-template specific stuff, so would probably want someone who has more knowledge of that to take a look. (Perhaps @marchello2000?)
@@ -27,7 +26,7 @@ | |||
String id; | |||
String schema; | |||
String type; | |||
List<ExpectedArtifact> expectedArtifacts; | |||
List<HashMap<String, Object>> expectedArtifacts; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we moving from a typed object to a generic Map
here? Are we expecting that expectedArtifacts
contains a list of things that aren't actually expected artifacts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only reason to move it to HashMap<String, Object>
is that it's easier to merge artifacts from different sources given that the other sources are using HashMap<String, Object>
(TemplateConfiguration.PipelineConfiguration
and PipelineTemplate.Configuration
).
I considered changing these 2 configuration classes to use ExpectedArtifact
instead but many tests failed because of the lack of Artifact boundArtifact
field in templates and configurations.
Given that orca is not using the expected artifacts in this class, I consider this change involves lower risk than doing a bigger refactoring in order to be able to use ExpectedArtifact
in the other cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method and property types should use an interface type, so these should change to Map<String, Object>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robzienert map type comment addressed
@@ -100,14 +100,18 @@ class DependentPipelineStarter implements ApplicationContextAware { | |||
|
|||
def trigger = pipelineConfig.trigger | |||
//keep the trigger as the preprocessor removes it. | |||
def expectedArtifacts = pipelineConfig.expectedArtifacts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this is reverting the fix that was made in #2430. Have you tested that you haven't re-introduced the bug that was fixed there?
|
||
if (parentPipelineStageId != null) { | ||
pipelineConfig.receivedArtifacts = artifactResolver?.getArtifacts(parentPipeline.stageById(parentPipelineStageId)) | ||
} else { | ||
pipelineConfig.receivedArtifacts = artifactResolver?.getAllArtifacts(parentPipeline) | ||
} | ||
|
||
// For pipelines with dynamic source, it is required to perform the following steps: | ||
// 1. Resolve source template artifact so the dynamic source expression can be evaluated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that I fully understand why we need to resolve artifacts twice here, and have some concerns about now always resolving artifacts twice. I think partly it's that I don't fully understand what is a "pipeline with dynamic source" is. Can you please give an example (or point to a test case) for what such a pipeline looks like and how it would get resolved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with pipeline with dynamic source I meant to have an expression to fetch source pipeline from artifacts such as
"source": "{% for artifact in trigger.artifacts %}{% if artifact.name == 'pipeline-template' && artifact.type == 'http/file' %}{{artifact.reference}}{% endif %}{% endfor %}"
here a test with dynamic parent:
Line 467 in 2e07fcc
def "should trigger v1 templated pipelines with dynamic source using prior artifact"() { |
On why we need to resolve artifacts twice, the first time we need it in order to load parent pipeline, once we have loaded the parent pipeline, we need to resolve artifacts again as new artifacts could have been found in parent pipeline.
@ezimanyi I hope my comments give you some clarification on this. Let me know if more explanation is needed. |
@xabierlaiseca : Thanks for the explanation, and the pointer to the test. Looking at that example, it seems like the only effect of the first It seems like it might be less complex and less risky of a change to leave a single pass of artifact resolution (happening after running the pre-processors as you have here) and have the template refer to Alternately I could also imagine just directly setting |
The context behind my extreme caution around this is that there were a lot of very subtle bugs in artifact resolution for templated pipelines in the numerous comments on spinnaker/spinnaker#2654. I spent a bunch of time fixing those, but the code is still more complex and not as well tested than I'd like so I want to be careful about introducing increased complexity. I have less direct experience with how the V1 template processing works (which is why my comments are more around the artifact resolution in |
...in/java/com/netflix/spinnaker/orca/pipelinetemplate/v1schema/V1SchemaExecutionGenerator.java
Show resolved
Hide resolved
return Optional.ofNullable(eas).orElse(Collections.emptyList()); | ||
} | ||
|
||
private List<HashMap<String, Object>> mergeExpectedArtifact( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just confirming this is the intent (which, looking at that usages, I think it is) if there are duplicates, the artifacts in the eas2
will "win", right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, that is the intent, this way an spinnaker configuration will be able to override an expected artifact in a template
Sorry, just saw this. |
I agree, seems like this should work, @xabierlaiseca what do you think? |
@ezimanyi @marchello2000 I tried I'll try the alternative way that was mentioned |
4d4b0eb
to
6f9408f
Compare
@ezimanyi @marchello2000 can you please have a look to this commit 6f9408f , I believe this is what you suggested instead of resolving artifacts twice but I would like to get some feedback about it from you |
Thanks, @xabierlaiseca, for reworking this. Unfortunately, I don't understand the subtleties of artifact resolution so I will let @ezimanyi review this |
@xabierlaiseca : Yes, the latest commit (6f9408f) is indeed what I was suggesting to avoid resolving artifacts twice. If that works for your use case then I think that would be more robust than always resolving twice. I think the only remaining question from my perspective is still that it appears this reverts #2430 (which stored and re-set the expected artifacts). Was that a deliberate change, or will this re-introduce the issue there? |
@ezimanyi regarding #2430 , that fix is covered in line https://github.com/spinnaker/orca/pull/3023/files#diff-4f3d52b85acf51b2ed51955fdbbb78e3R165 |
2733ccb
to
0fee5d9
Compare
…plates When expected artifacts are defined in a template that is sourced dynamically, expected artifacts are not added to the execution. Expected artifacts can be defined in `TemplatedPipelineRequest`, `TemplateConfiguration` and `PipelineTemplate` objects, so a merge strategy is required. Given expected artifacts have a unique `id`, artifacts with same `id` in these object will be overridden. The artifacts with higher priority are the ones in `TemplatedPipelineRequest`, then `TemplateConfiguration` and finally `PipelineTemplate`.
@ezimanyi @marchello2000 given @PerGon's comment, I believe the PR is ready to be merged, I've just squashed my commits. Could you please re-review and merge it you consider is now ready? |
OK, this final version looks good to me! Thanks for addressing all of the comments! |
When expected artifacts are defined in a template that is sourced dynamically,
expected artifacts are not added to the execution.
Expected artifacts can be defined in
TemplatedPipelineRequest
,TemplateConfiguration
andPipelineTemplate
objects, so a merge strategyis required. Given expected artifacts have a unique
id
, artifacts withsame
id
in these object will be overridden. The artifacts with higherpriority are the ones in
TemplatedPipelineRequest
, thenTemplateConfiguration
and finally
PipelineTemplate
.