-
Notifications
You must be signed in to change notification settings - Fork 642
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
Merging Properties and POM based configuration #948
Conversation
Codecov Report
@@ Coverage Diff @@
## master #948 +/- ##
============================================
+ Coverage 51.4% 51.65% +0.25%
- Complexity 1232 1350 +118
============================================
Files 144 147 +3
Lines 7276 7445 +169
Branches 985 1121 +136
============================================
+ Hits 3740 3846 +106
- Misses 3220 3232 +12
- Partials 316 367 +51
|
Ping @rhuss |
Awesome, thanks ! I'm on the road this week (and was on PTO last week), so I probably can review the PR only at the beginning of next week. 'hope this is ok ... |
Great, OK! |
Looks great, thanks again ! I like the way how Some minor nits about the naming: I would probably made it more explicit that it is about naming, and What do you thinks about a
? Not 100% sure about the _combine suffix (and whether I understand it on a first read ;-). Do you have a use case handy where this required (and can't be solved otherwise) ? |
Hm yes I was going back and forth with Are you suggesting having mergePolicy instead of The Basically, each ConfigKey has a CombinePolicy assigned to it, for most it's Replace. That means the highest prioritised value will be used without any sort of merge. The defaults for the different ConfigKeys are certainly up for discussion. For example, labels, ulimit, and a few others could very well make sense to use Merge by default. |
yes, I think has its about merging configurations maybe this should be reflected in the name of the config option, too. But if you like I see the point with specifying how to combine values when merging, not 100% sure about how we expose this to the user. Let's discuss this next week, but you can assume that the PR will get in dmp asap (except maybe for minor tweaks), so that you could start migrating your projects already. |
I'm thinking that first step is "sourcing values" i.e. from config and/or properties, in some order, and second step is "combining values" to get the final configuration, where "combine" is in some cases merge and in some cases replace.. Although replace might be bad word too, since "replace" indicates that we are replacing something (when all we do is really taking the value with highest priority). One thing which is not covered is clearing values. For example if we have some property in config, which we want to unset with properties. In some cases a blank string might work but.. Anyway, great, looking forward to further discuss next week and merge :) |
@rhuss Hi, had any time to look at this yet? :) |
@stromnet yeah, sorry. Back from PTO and conference, and already kneedeep in work again ;-( I thought a bit about the naming and what do you think about this suggestion: <external>
<type>properties</type>
<mode>only|override|fallback|skip</mode>
</external> The advantage would be
I don't mind much that we don't have yet support for clearing values. We should tackle this when it becomes a requirement (i.e. a valid use case exists). wdyt ? If we agree on the naming I would jump into a reviewer later today or tomorrow. |
@rhuss welcome back :) Good point on So, What would It doesn't address the override/fallback scenarios where we want to do a merge, for example a env map where we want to merge both properties from POM and add some from properties. Or are you happy with the "combine policy" proposal? |
Do you mean the |
Ah, of course. Yes!
Ok, great! So, existing code should be changed a bit then, but mostly around the |
Sounds like a plan ;-) 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.
Hey, awesome work ! Quite a lot of changes required, especially for separating default values implicitly set in the configuration classes.
I'm not sure whether I really love all the raw classes or whether default value handling should be completely different. But that another problem, which we need to think about later (e.g. use 'naked classes' for the configuraton and add only default values when used, or an adapter with default values wrapped around the original configuration classes with null values). Let's check that later, shouldn't be a hurdle for this PR.
Please don't get overwhelmed by the amount of comments. (Sorry, but thats my usual style of review, so it takes a always a bit until I jump on one).
Just check whether the comments make sense to you, and whether you might want to change it yourself. If not, I can do it later, too. Of course, I'm open for discussions, too ;-)
Thanks again, I really like the feature, but we need also to be sure to not break stuff (too much ;-).
| Sets an environment variable. E.g. `<docker.env.JAVA_OPTS>-Xmx512m</docker.env.JAVA_OPTS>` sets the environment variable `JAVA_OPTS`. Multiple such entries can be provided. This environment is used both for building images and running containers. The value cannot be empty but can contain Maven property names which are resolved before the Dockerfile is created. | ||
| Sets an environment variable used in build and run. E.g. `<docker.env.JAVA_OPTS>-Xmx512m</docker.env.JAVA_OPTS>` sets the environment variable `JAVA_OPTS`. Multiple such entries can be provided. This environment is used both for building images and running containers. The value cannot be empty but can contain Maven property names which are resolved before the Dockerfile is created. | ||
|
||
| *docker.buildEnv.VARIABLE* |
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.
actually the table in this document is order alphabetically so that one can easier find the right properties. This should be kept this was, but I see that it makes also sense to keep the env vars together.
wdyt about renaming buildEnv
to envBuild
? (same for runEnv
)
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.
Had the same thought. Problem is, IIRC, that the existing code looks for properties beginning withdocker.env
prefix. Consequently, if I had a property docker.envRun.JAVA_OPTS=-Xmx512m
it was adding Run.JAVA_OPTS=-Xmx512m
in both run and build env.. Or at least something along those lines, don't recall exactly.
Could perhaps be fixed by altering property matching?
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 did not recall correct. And luckily enough I had described it there: #941
I was trying to use env.run
, which suffered this problem. But envRun
should be fine. Let's change!
@@ -51,8 +51,11 @@ | |||
DOCKER_FILE, | |||
DOCKER_FILE_DIR, | |||
ENTRYPOINT, | |||
@Deprecated |
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.
Wouldn't call it deprecated, I still think for simplicities reason it makes sense to keep a single env
, as some build only do build or runs (and not both).
ENV, | ||
ENV_PROPERTY_FILE, | ||
ENV_BUILD("buildEnv", ValueCombinePolicy.Merge), |
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.
again an argument to call it 'envBuild', to keep the mapping of key name to the actual value.
} | ||
|
||
// Shortcircuit | ||
if(values.isEmpty()) |
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.
Please add braces, we do this even for single line ifs. (Also maybe adapt to the spacing, but I'm not so dogmatic here).
Also for the other 'ifs'
@@ -119,22 +123,34 @@ | |||
WATCH_INTERVAL("watch.interval"), | |||
WATCH_MODE("watch.mode"), | |||
WATCH_POSTGOAL("watch.postGoal"), | |||
WATCH_POSTEXEC("watch.postExec"), |
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.
good catch, thanks for adding!
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 of these seems to lack documentation in _property_configuration.adoc
but leaving that to someone else.. :)
@@ -199,8 +199,8 @@ private void clearAllMaps() { | |||
|
|||
RunImageConfiguration runConfig = imageConfig.getRunConfiguration(); | |||
WaitConfiguration waitConfig = runConfig != null ? runConfig.getWaitConfiguration() : null; | |||
this.shutdownGracePeriod = waitConfig != null ? waitConfig.getShutdown() : 0; | |||
this.killGracePeriod = waitConfig != null ? waitConfig.getKill() : 0; | |||
this.shutdownGracePeriod = waitConfig != null ? waitConfig.shutdown() : 0; |
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.
Could we just keep getShutdown()
and make the null handling here (to keep the number of different getters lower)
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.
Makes sense, since that one is only used there.
this.shutdownGracePeriod = waitConfig != null ? waitConfig.getShutdown() : 0; | ||
this.killGracePeriod = waitConfig != null ? waitConfig.getKill() : 0; | ||
this.shutdownGracePeriod = waitConfig != null ? waitConfig.shutdown() : 0; | ||
this.killGracePeriod = waitConfig != null ? waitConfig.kill() : 0; |
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.
dito (see above)
@@ -69,7 +69,7 @@ public void wait(ImageConfiguration imageConfig, Properties projectProperties, S | |||
|
|||
private int getTimeOut(ImageConfiguration imageConfig) { | |||
WaitConfiguration wait = getWaitConfiguration(imageConfig); | |||
return wait != null ? wait.getTime() : 0; | |||
return wait != null ? wait.time() : 0; |
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.
see above
@@ -107,7 +107,7 @@ private String extractCheckerLog(List<WaitChecker> checkers) { | |||
} | |||
} | |||
|
|||
if (wait.getHealthy()) { | |||
if (wait.healthy()) { |
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.
see above
* @param project Project to extract Properties from | ||
* @return | ||
*/ | ||
public static Properties getPropertiesWithSystemOverrides(MavenProject project) { |
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 pretty sure we use such a functionality already somewhere else, so would be awesome if we would have a common approach.
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.
Great review! Lots of good points, have commented a few of them. Will get on to fix the no-discussion ones in the meantime. |
Ok, so as always, lots of stuff came in the way today and I did not have the time to do as much as I wanted... But just pushed some minor fixes at least. May be short on time next week, so not sure how much I'm going to be able to finish.. |
@stromnet thanks for the feedback ! No worries, I'm currently also very busy, but happy to pick up as soon as you're done. thanks ! |
Got some time over, pushed most (all?) minor changes. And one inline-comment on null vs Java 8 above. |
cool, thanks ! I'm just on the road for Javaland, but hopefully I find some train-time to make the final review. Let's get it merged asap ;-) |
@rhuss There, I think I've addressed all issues now I think, except alternative solution for repeated When updates have been reviewed, I suggest we squash everything to single commit.. :) |
just a heads up: I'm going to merge the PR this afternoon when I'm back |
@rhuss Great :) Any objections to me squashing everything to one commit and re-pushing it before you do that? |
Addresses fabric8io#386. Note that it was not possible to use "env.run/build", which would have matched well with other properties, because we already have the "env" matcher (which would have matched env.run too, injecting bad properties). Signed-off-by: Johan Ström <johan@stromnet.se>
…ions Allows that an image is configured from both POM file and properties. Is activated by either setting <source>properties,pom</source> in <external>, or for single image projects by setting property "docker.externalPropertyConfiguration.source=properties,pom". Most properties will be fully replaced, but some are merged (see ConfigKey for list of default combination policies) Signed-off-by: Johan Ström <johan@stromnet.se>
4948880
to
ac1db28
Compare
Rebased on master and re-pushed (same branch) with squashed commits. |
did a quick re-review of your changes and all looks good. Thanks a lot ! So, let's merge it now. However, for the next steps I really would like to streamline the default handling (i.e. how to provide default values, maybe getting rid of the "raw" methods and null checks). Not sure how to tackle this, but would be super happy if you could give it a spin. Thanks again a ton, it's really a super valuable feature. It does not look big, but make this plugin much more flexible. |
Perfect, thanks! Eagerly waiting for the release then :) One oops: noticed my squashed commit msg mentions the wrong property. |
(originally discussed in #938. Branch based on commit in #941 with run/buildEnv)
Edit: NOTE The following details are NOT what was finally implemented, instead a
<mode>
property is used. Please refer to the final docs rather than details in this body.This adds supports to use both Properties based configuration and POM based configuration to configure the same image. This is done by adding the
source
configuration to the<external>
section, which can have one of the following values:properties
- default, same as existing properties based configuration (ie. no merge)pom, properties
- merge pom configs and properties, with values in POM having priorityproperties, pom
- merge pom configs and properties, with values in properties having prioritypom
- pretty useless, same as not having at all)Can also be enabled by pure properties (only makes sense for single image), by setting the property
docker.externalPropertyConfiguration.source
to a validsource
value. This is useful if we want to add properties from site-wide config for example settings.xml, for example addingrunEnv.http_proxy
without touching every POM using the plugin.Properties are loaded from Maven Project properties merged with System properties (Maven -D flags).
Merging on value level takes place for only a few specific properties by default, for most values it does not make sense to merge (i.e.
runCmd
,from
or any other single values).Which values to be merged/replaced are controlled by a new configuration on the
ConfigKey
enum. This can be overridden by setting the_combine
property suffix.h2. Examples
Set some properties through -D flags (requires that external is activated in POM)
Set some properties through -D flags, also activating external from -D flag:
Override merge policy for runEnv map (only use the one defined in properties, ignoring any in POM):