-
Notifications
You must be signed in to change notification settings - Fork 211
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
Snapshot for standalone planner #378
base: master
Are you sure you want to change the base?
Conversation
ee99ef0
to
0b23291
Compare
vars/deployPlannerSnapshot.groovy
Outdated
body() | ||
|
||
def yaml | ||
def openShiftProject = config.openShiftProject |
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 not just use
config.openShiftProject
instead of using an additional local variable? - Since config is set to empty dictionary in line 7, isnt
config.openShiftProject
going to be empty here always?
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 have used several times later in the code, instead of reading every time from the map I thought local var is good. Not sure though.
.delegate
does kind of magic, it will export values passed to function and keep filling up the empty config with provided values if I get it right.
def originalImageName = config.originalImageName | ||
def newImageName = config.newImageName | ||
def deploymentName = config.githubRepo | ||
def providerLabel = config.providerLabel ?: 'fabric8' |
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.
All local variables except this would be null. Maybe you forgot a config param in the function signature?
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.
confuses me as well, and follows what is done in https://github.com/fabric8io/fabric8-pipeline-library/blob/master/vars/deployOpenShiftSnapshot.groovy#L11 Is there some magic involved?
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.
as mentioned above in comment - https://github.com/fabric8io/fabric8-pipeline-library/pull/378/files#diff-e29e1891af9b97dd7f7137d912b468acR9 this line is responsible
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.
@jaseemabid wonder why you thought all local variables would be null
? wouldn't body()
initialise these?
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.
@pranavgore09 @jaseemabid hopefully this may make sense to you ...
class Body {
def closure = {
println delegate
println "closure: foo: ${foo}"
foo = 'barrrr'
bar = 'baaazzz'
}
}
def config = [ foo: "bar"]
def obj = new Body()
def body = obj.closure
body.delegate = config
println "main: foo: ${config.foo}"
println "main: bar: ${config.bar}"
body()
println "main: foo: ${config.foo}"
println "main: bar: ${config.bar}"
Output:
main: foo: bar
main: bar: null
class delegate
closure: foo: bar
main: foo: barrrr
main: bar: baaazzz
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 in case you are wondering where I got this idea from :) - https://stackoverflow.com/a/23450944
vars/deployPlannerSnapshot.groovy
Outdated
def flow = new io.fabric8.Fabric8Commands() | ||
def utils = new io.fabric8.Utils() | ||
|
||
openShiftProject = openShiftProject + '-' + utils.getRepoName() |
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.
Define the variable here, avoid that mutation
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 done, now only one declaration in a869abe
vars/deployPlannerSnapshot.groovy
Outdated
} | ||
// cant use writeFile as we have long filename errors | ||
sh "echo '${yaml}' > snapshot.yml" | ||
|
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.
There is probably a groovy function called write, so that we dont have to spawn a subshell here. There must be something similar to write('snapshot.yml', yaml)
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.
kept is as it is, but added the error that I faced in a comment above it a869abe#diff-e29e1891af9b97dd7f7137d912b468acR39
vars/deployPlannerSnapshot.groovy
Outdated
def utils = new io.fabric8.Utils() | ||
|
||
openShiftProject = openShiftProject + '-' + utils.getRepoName() | ||
container('clients') { |
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.
Spawning the clients container just to get oc binary seems a bit too much. Should probably add the 'oc' binary to the jenkins builder image and scrap this. Need not be part of this PR obviously, but something that needs a look. WDTY @rupalibehera @chmouel @sthaha
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 am not sure what you meant by jenkins builder image
; not an area I know. is it the jenkins master image?
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.
@sthaha Yes. I meant master. Looks like we bring in yet another repository and image and container just for the oc binary from https://github.com/fabric8io-images/builder-clients, which is what I was hoping to get rid of.
return true | ||
} catch (err) { | ||
echo "waiting for ${deploymentName} to be ready..." | ||
return false |
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.
Is this waitUntill
a tight loop? Do you think there should be a sleep if it fails? Is that inbuilt? If we add a sleep before the return false
, we can remove the sleep 10
above?
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.
Nice patch! Looks good to me, some minor comments thou.
vars/deployPlannerSnapshot.groovy
Outdated
body() | ||
|
||
def yaml | ||
def openShiftProject = config.openShiftProject |
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.
how about def openshiftProject = config.openshiftProject + '-' + utils.getRepoName()
so that this variable isn't overwritten in line 24?
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! done in a869abe
vars/deployPlannerSnapshot.groovy
Outdated
def flow = new io.fabric8.Fabric8Commands() | ||
def utils = new io.fabric8.Utils() | ||
|
||
openShiftProject = openShiftProject + '-' + utils.getRepoName() |
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.
IMHO, keeping variables as immutable as possible makes it easy to reason with the code. Here openshiftProject isn't acting like an accumulator (sum, product etc...) so we can keep it immutable like mentioned in the comment above
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.
👍 fixed a869abe
vars/deployPlannerSnapshot.groovy
Outdated
error 'Change author is not a collaborator on the project, aborting build until we support the [test] comment' | ||
} | ||
|
||
yaml = flow.getUrlAsString(openShiftTemplate) |
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.
same pattern here, made me think that yaml is getting overwritten in the line below. how about:
def url = flow.getUrlAsString(openshiftTemplate)
def originalImage = "- image: ${...}"
def newImage = "- image: ${...}"
yaml = Pattern.compiler(originalImage).matcher(url).replaceFirst(newImage)
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.
thanks, fixed.
vars/deployPlannerSnapshot.groovy
Outdated
sh "echo '${yaml}' > snapshot.yml" | ||
|
||
container('clients') { | ||
try { |
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.
we could convert this into a reusable method switchProject(project)
@pranavgore09 Several comments inline. AFAIK, it fundamentally boils down to a
I guess a straightforward shell script would look a lot saner than so many levels of indirection caused by this library. The patch looks fine & it seems to fit in with the rest of the code. LGTM except the inline comments. |
cc2a0fb
to
a869abe
Compare
Added new groovy script for building and deploying plannerUI standalone snapshot in CI.
a246360
to
0490a4d
Compare
@jaseemabid @sthaha I have removed |
def originalImage = "- image: ${originalImageName}:(.*)" | ||
def newImage = "- image: ${newImageName}" | ||
def compiledYaml = Pattern.compile(originalImage).matcher(yaml).replaceFirst(newImage) | ||
|
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.
@pranavgore09 Its slightly odd that we use string matching and regular expressions to get data out of a structured data interchange format. I would have expected to see something like this.
def yaml = Yaml.parse(flow.getUrlAsString(openShiftTemplateURL))
yaml.services[1].image = config.newImage // Whatever the real path is
def snapshot = yaml.toString()
// Remove the check below, because that wont fail now.
I'm OK with this code, this might be written this way because of other nuances like groovy sandbox or something which we don't know.
Point being, this feels like a very poor groovy implementation of
wget openShiftTemplate > snapshot.yml
sed -i -e 's/oldImage/newImage/g' snapshot.yml
and that feels really odd.
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 indeed has a method to parse yaml but @jaseemabid mentioned I feel this is consistent with the existing implementation so lets go ahead with this and fix both later as a separate issue.
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.
Looks good to me
def originalImageName = config.originalImageName | ||
def newImageName = config.newImageName | ||
def deploymentName = config.githubRepo | ||
def providerLabel = config.providerLabel ?: 'fabric8' |
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.
@jaseemabid wonder why you thought all local variables would be null
? wouldn't body()
initialise these?
def originalImage = "- image: ${originalImageName}:(.*)" | ||
def newImage = "- image: ${newImageName}" | ||
def compiledYaml = Pattern.compile(originalImage).matcher(yaml).replaceFirst(newImage) | ||
|
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 indeed has a method to parse yaml but @jaseemabid mentioned I feel this is consistent with the existing implementation so lets go ahead with this and fix both later as a separate issue.
LGTM. Merge 👍 |
Just a general thought I wanted to share - this kind of functions should not belong to the "library" as they are very specific to particular projects. That makes them unshareable essentially. So either we could decompose it to more "generic purpose" functions and reuse from within Planner |
I have questioned this approach of one-off functions since we started using it. I don't know how we can move away from it quickly. So we might just accept this but work toward a better solution. |
@joshuawilson timebox it for 1 day for someone in your team and try? I think it's easily done based on the guide I shared above. |
thanks, @bartoszmajsak @joshuawilson for taking a look, but when I started working on this, my intention was to deploy snapshot for the standalone planner, over a period of time it changed to a greater extent and as of now that change does not have any static things in it, any specific setup inside. Except the essentially it deploys application given in openshiftTemplate. here The only line is regex matcher that seems to be static, but IMO that is fine. |
Thanks for explanation @pranavgore09, makes sense :) Nice work! My comment was a more a general statement. Maybe in this given case we only need to rename the function then. But we do have a lot of other |
@bartoszmajsak @joshuawilson There is a whole lot of project specific code in the library and I think we all agree that it doesn't make much sense. We will need to take a look at it as a whole and trim down a lot. For example, #372 |
Added a new groovy script that will deploy snapshot and report the route URL on the PR.
Similar to deployOpenShiftSnapshot
This is being consumed in fabric8-ui/fabric8-planner#2426