-
Notifications
You must be signed in to change notification settings - Fork 6
sktm should make multiple attempts to query Jenkins #116
Conversation
Pull Request Test Coverage Report for Build 405
💛 - Coveralls |
Hi Vector! If you get to the final version of the pull, can you please squash the commits into a single one and let us know so we can check it? |
Hi Veronika, the commits are squashed, please check it, thanks! |
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.
Okay, finally got to check this out :) I like the idea of resiliency eg. in case of temporary network failures, but it needs more thought. Would it be possible to make the retry count a command line option with a default value, and use similar logic every time sktm tries to communicate with jenkins, not only in this method? And in case we still can't reach jenkins after all those retries, abort with exception or something similar?
Veronika, I have updated the related .py files to support a command line option, please check again, thanks! |
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 Vector, this is looking much better! :) I have some smaller comments for improvement, but the main idea is good. Can you also exchange the rest of get_job
and get_build
calls in the repo for the new methods so we have the resiliency everywhere?
sktm/executable.py
Outdated
@@ -38,6 +38,7 @@ def setup_parser(): | |||
parser.add_argument("--jurl", help="Jenkins URL") | |||
parser.add_argument("--jlogin", help="Jenkins login") | |||
parser.add_argument("--jpass", help="Jenkins password") | |||
parser.add_argument("--jretry", help="Counter to retry Jenkins") |
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.
You can add type=int
keyword argument here and then don't need to cast the option to int
later. Granted, the value read from the config file won't be int
, so you can combine this comment with the one below (about the default value assignment in load_config
and do the retyping there.
Can you also mention the default value in the help string please? A simple (defaults to X)
at the end is enough.
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 default value is added to the help string.
sktm/jenkins.py
Outdated
@@ -23,7 +23,8 @@ | |||
|
|||
class JenkinsProject(object): | |||
"""Jenkins project interface""" | |||
def __init__(self, name, url, username=None, password=None): | |||
def __init__(self, name, url, username=None, password=None, | |||
retry_cnt="30"): |
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 don't think this will work (that said, the username
and password
params don't need the defaults either) -- if the option is not present, cfg.get('jretry')
will return None
, which is a perfectly valid value, and since the option will be passed the default is never used.
Instead, you should either assign a default value at the end of the load_config
method (if the option is not None
) or in this method (the first one is preferred)
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.
Does this change work fine? (I didn't update load_config() yet)
- parser.add_argument("--jretry", help="Counter to retry Jenkins")
+ parser.add_argument("--jretry", help="Counter to retry Jenkins",
+ type=int, default=30)
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.
This would work for command line options but not the config file. You'll still need to add the logic for retyping it because of that
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.
OK, Added.
sktm/jenkins.py
Outdated
@@ -320,6 +326,56 @@ def build(self, baserepo=None, ref=None, baseconfig=None, | |||
logging.info("submitted build: %s", build) | |||
return build.get_number() | |||
|
|||
def __get_job(self): | |||
""" | |||
Get Jenkens job by job name. Retry Jenkins N times in case of temporary |
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.
Can you mention the retry_count
and the default value here instead of N
so it's clear where the value comes from?
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.
sure.
sktm/jenkins.py
Outdated
network failures. | ||
|
||
Return: | ||
(job, None) if succeed, else return (None, e) where e is the last |
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.
Since the exception is going to be raised anyways, wouldn't this be too complicated? Can we just return the job if we succeed, and raise the exception if we can't reach Jenkins at all?
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.
Sure. Updated.
sktm/jenkins.py
Outdated
(job, None) if succeed, else return (None, e) where e is the last | ||
exception. | ||
""" | ||
retry_cnt = self.retry_cnt |
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 really necessary? Why not use self.retry_count
directly?
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.
Use self.retry_cnt instead.
sktm/jenkins.py
Outdated
logging.error("fail to get job after retry %d times" % retry_cnt) | ||
return (None, e) | ||
|
||
def __get_build(self, job, buildid): |
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 comments as with __get_jobid
here :)
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.
Done.
Thanks Veronika for your review, I have updated the related files according to your comments, please take a look again. |
Reopen the PR after updating load_config(). |
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 sorry, but the load_config
changes in their current state won't work. Also, can you exchange the rest of job and build retrievals for the new methods?
sktm/executable.py
Outdated
@@ -47,6 +49,9 @@ def setup_parser(): | |||
parser.add_argument("--jurl", help="Jenkins URL") | |||
parser.add_argument("--jlogin", help="Jenkins login") | |||
parser.add_argument("--jpass", help="Jenkins password") | |||
parser.add_argument("--jretry", | |||
help="Counter to retry Jenkins, default to 30", | |||
type=int, default=30) |
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 use a numeric default here instead of the added constant?
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.
Sorry I forgot to replace the number with the added constant. Now default = 30 is removed and help string is updated.
@@ -205,6 +210,9 @@ def load_config(args): | |||
else: | |||
cfg['report_footer'] = os.path.abspath(cfg['report_footer']) | |||
|
|||
if not cfg.get('jretry'): |
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.
This condition will never follow through because of the default added to the parser. Because of that, the value will also never be updated by the one from configuration file. I think it would be easier to remove the default from the parser and keep this condition, with an else
branch that would retype the value to int
(the value read form configuration file is a string, so leaving that part out will break sktm), what do you say?
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 misunderstood the logic to load a configuration variable from file. It's updated, pls take a look again.
sktm/jenkins.py
Outdated
@@ -320,6 +326,51 @@ def build(self, baserepo=None, ref=None, baseconfig=None, | |||
logging.info("submitted build: %s", build) | |||
return build.get_number() | |||
|
|||
def __get_job(self): | |||
""" | |||
Get Jenkens job by job name. Retry Jenkins $retry_cnt times in case |
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.
This is a really minor nitpick, but can we do self.retry_cnt
instead of the dollar notation? First, it's missing the self
notion and self.retry_cnt
and retry_cnt
are two very different variables so someone new reading the code would get pretty confused; and secondly, well, it's python and not bash :)
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.
Well, now use self.retry_cnt instead of $retry_cnt, please check. Again, thank you very much for your review.
Veronika, I updated the related files according to your comments, please take a look again. Your comments are much appreciated! |
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 Vector, functionality-wise it's looking good! However, I'm still missing the exchange of the rest of the server.get_job
and job.get_build
calls. Can you add those?
sktm/executable.py
Outdated
@@ -205,6 +210,12 @@ def load_config(args): | |||
else: | |||
cfg['report_footer'] = os.path.abspath(cfg['report_footer']) | |||
|
|||
jretry = cfg.get('jretry') |
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's no need for this - if not cfg.get('jretry')
and cfg['jretry'] = int(cfg.get('jretry'))
should work just fine :)
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.
Agree, updated.
Thanks Veronika for review again, I have updated the rest of server.get_job and job.get_build calls to use __get_job()/__get_build(). And I'm not sure job.get_last_build() / job.get_next_build_number() should be enhanced to avoid random networking failures, so just leave them as they are. If you have more concerns/comments, please let me know, thank you very much. |
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 Vector, LGTM now! I'd say it would be cool to have the rest of methods that query Jenkins modified in a similar way, if you want to implement them feel free to do so and submit another pull
Thanks Veronika again. Okay, I'll implement them this week and file another PR for review. |
Since self.jk.is_build_complete() throws an exception when jenkins cannot be reached, we try to use 'try ... except ...' in is_build_complete() to avoid exceptions.