-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Add OomScoreAdj to "docker service create" and "docker compose" #5145
base: master
Are you sure you want to change the base?
Conversation
7c5a646
to
4a82dc0
Compare
6f0f551
to
fd3a9cd
Compare
@@ -0,0 +1,680 @@ | |||
{ |
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.
Schema 3.13 was added in #5125, which has not been released yet, and will be for the v27.0 release, so we don't need to add a new schema and can update 3.13 instead.
cli/command/container/opts.go
Outdated
OomScoreAdj: copts.oomScoreAdj, | ||
OomScoreAdj: int(copts.oomScoreAdj), |
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.
Both sides should already be an int
I think, so this change should probably be removed.
opts/opts.go
Outdated
|
||
type OomScoreAdj int64 | ||
|
||
func (o *OomScoreAdj) Type() string { return "int64" } | ||
|
||
func (o *OomScoreAdj) Value() int64 { return int64(*o) } | ||
|
||
func (o *OomScoreAdj) String() string { | ||
|
||
val := strconv.FormatInt(int64(*o), 10) | ||
return val | ||
} | ||
|
||
func (o *OomScoreAdj) Set(value string) error { | ||
|
||
var conv int64 | ||
conv, err := strconv.ParseInt(value, 10, 64) | ||
if err != nil || conv < -1000 || conv > 1000 { | ||
return err | ||
} | ||
*o = OomScoreAdj(conv) | ||
return nil | ||
} |
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.
Bit on the fence here if we should have a special option-type for this. It does allow for validation on the client-side, but also makes assumption about what the daemon-side allows (given; it's unlikely to change); for docker run
it looks like we leave the validation to the API, and using a regular IntVar
option;
cli/cli/command/container/opts.go
Line 306 in 64206ae
flags.IntVar(&copts.oomScoreAdj, "oom-score-adj", 0, "Tune host's OOM preferences (-1000 to 1000)") |
2b9f928
to
25083e3
Compare
opts/opts.go
Outdated
if err != nil || conv < -1000 || conv > 1000 { | ||
return err | ||
} |
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.
In the case where err == nil
but conv
is out of range, the Set()
call will silently be a no-op. Either generate a client-side error, or (preferably) do what @thaJeztah recommends and leave range validation to the API / daemon.
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, I think we can keep it simple for now, and do the same as we do for docker run
, which is a regular IntVar
.
I tend to reduce client-side validation to a minimum to keep the CLI agnostic and make the daemon "source of truth". That's not all set in stone, and there are some grey areas where it's worth the trade-ff but I'd like to avoid the CLI making assumptions that may not be correct.
"type": "object", | ||
"type": "object", | ||
|
||
"properties": { | ||
"driver": {"type": "string"}, | ||
"options": { | ||
"type": "object", | ||
"patternProperties": { | ||
"^.+$": {"type": ["string", "number", "null"]} | ||
} | ||
} | ||
}, | ||
"additionalProperties": false | ||
"properties": { | ||
"driver": {"type": "string"}, | ||
"options": { | ||
"type": "object", | ||
"patternProperties": { | ||
"^.+$": {"type": ["string", "number", "null"]} | ||
} | ||
} | ||
}, | ||
"additionalProperties": 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.
Can you undo these whitespace changes 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.
Same here (missing newline at end of file)
opts/opts.go
Outdated
func (o *OomScoreAdj) String() string { | ||
|
||
val := strconv.FormatInt(int64(*o), 10) | ||
return val |
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.
Don't think we need an intermediate var here, and there's a stray empty line at the start of the function
func (o *OomScoreAdj) String() string { | |
val := strconv.FormatInt(int64(*o), 10) | |
return val | |
func (o *OomScoreAdj) String() string { | |
return strconv.FormatInt(int64(*o), 10) |
opts/opts.go
Outdated
if err != nil || conv < -1000 || conv > 1000 { | ||
return err | ||
} |
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, I think we can keep it simple for now, and do the same as we do for docker run
, which is a regular IntVar
.
I tend to reduce client-side validation to a minimum to keep the CLI agnostic and make the daemon "source of truth". That's not all set in stone, and there are some grey areas where it's worth the trade-ff but I'd like to avoid the CLI making assumptions that may not be correct.
cli/command/service/update.go
Outdated
func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags *pflag.FlagSet, spec *swarm.ServiceSpec) error { | ||
|
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 remove the whitespace here?
cli/command/service/update.go
Outdated
if anyChanged(flags, flagOomScoreAdj) { | ||
|
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 remove whitespace here as well?
cli/command/service/update.go
Outdated
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{}) | ||
|
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 here (whitespace)
cli/command/service/create.go
Outdated
@@ -68,6 +68,7 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command { | |||
flags.SetAnnotation(flagSysCtl, "version", []string{"1.40"}) | |||
flags.Var(&opts.ulimits, flagUlimit, "Ulimit options") | |||
flags.SetAnnotation(flagUlimit, "version", []string{"1.41"}) | |||
flags.Var(&opts.oomScoreAdj, flagOomScoreAdj, "oom score adjustment (-1000 to 1000)") |
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 other comments; this could probably just be an flags.IntVar
25083e3
to
feaf642
Compare
Signed-off-by: plaurent <[email protected]>
feaf642
to
e174fe5
Compare
opts/opts.go
Outdated
conv, _ = strconv.ParseInt(value, 10, 64) | ||
*o = OomScoreAdj(conv) |
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.
If value
is not parseable as a number, the option gets silently set to 0? That doesn't seem 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.
I've run into silent defaults over multiple code bases, if we want different/better standards I didn't see anything documented.
Example...
Line 454 in e174fe5
return "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.
I've run into silent defaults over multiple code bases
What do "silent defaults" mean to you? Could you please elaborate?
Example...
You have linked to the definition of the String()
method of a pflag.Value
implementation, which contains a documented special case for how its zero value is formatted for user display.
Lines 448 to 450 in e174fe5
// NOTE: In spf13/pflag/flag.go, "0" is considered as "zero value" while "0 B" is not. | |
// We return "0" in case value is 0 here so that the default value is hidden. | |
// (Sometimes "default 0 B" is actually misleading) |
I'm not following how this is relevant to the topic being discussed. Could you please explain?
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 consider silent defaults to be any configuration options that are:
1.) set to values that have to be infered
2.) not explicitly documented outside of source code
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 still lost. Why are we on this tangent about silent defaults? What do silent defaults have to do with a (pflag.Value).Set()
method?
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 no tangent, I'm not worried about this. I'm just answering your question.
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.
Claiming that you have answered my question is not an answer. Please answer my question:
What do silent defaults have to do with a
(pflag.Value).Set()
method?
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 didn't actually reference that, you did.
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.
func (o *OomScoreAdj) Set(value string) error
, the body of which is the context for this discussion thread, implements a Set
method necessary for *OomScoreAdj
to satisfy the pflag.Value
interface. In other words, func (o *OomScoreAdj) Set(value string) error
is a (pflag.Value).Set()
method.
cli/command/service/opts.go
Outdated
@@ -529,6 +529,7 @@ type serviceOptions struct { | |||
capAdd opts.ListOpts | |||
capDrop opts.ListOpts | |||
ulimits opts.UlimitOpt | |||
oomScoreAdj opts.OomScoreAdj |
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.
oomScoreAdj opts.OomScoreAdj | |
oomScoreAdj Uint64Opt |
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.
That's an unsigned 64 bit integer for a value that ranges from -1000 to 1000
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.
My bad. You're correct; Uint64Opt
would not be appropriate. No custom Value
type is needed at all, since it's just a signed int.
oomScoreAdj opts.OomScoreAdj | |
oomScoreAdj int |
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 was a custom type originally because I had a range constraint in place. It should be fine, I need to fix the pipeline issues.
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 was a custom type originally because I had a range constraint in place.
The history of how this PR has evolved is irrelevant. The custom type is not needed in the current iteration, therefore merging this PR with the custom type in place increases the ongoing maintenance cost of this project without any offsetting benefit.
It should be fine, I need to fix the pipeline issues.
Please stay on topic.
opts/opts.go
Outdated
type OomScoreAdj int64 | ||
|
||
func (o *OomScoreAdj) Type() string { return "int64" } | ||
|
||
func (o *OomScoreAdj) Value() int64 { return int64(*o) } | ||
|
||
func (o *OomScoreAdj) String() string { | ||
return strconv.FormatInt(int64(*o), 10) | ||
} | ||
|
||
func (o *OomScoreAdj) Set(value string) error { | ||
|
||
var conv int64 | ||
conv, _ = strconv.ParseInt(value, 10, 64) | ||
*o = OomScoreAdj(conv) | ||
return nil | ||
} |
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 already exists a generic Uint64Opt
type in the cli/command/service
package. No need to define a new one.
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.
That's an Unsigned 64 bit integer
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.
Right, my mistake. You don't need any custom type at all! https://pkg.go.dev/github.com/spf13/pflag#FlagSet.IntVar
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #5145 +/- ##
==========================================
- Coverage 61.42% 61.40% -0.03%
==========================================
Files 298 298
Lines 20797 20813 +16
==========================================
+ Hits 12775 12780 +5
- Misses 7109 7119 +10
- Partials 913 914 +1 |
bd276ea
to
cf1a770
Compare
cf1a770
to
ef69fb9
Compare
Signed-off-by: plaurent <[email protected]>
ef69fb9
to
02761fd
Compare
- What I did
I added oom-score-adj flag to docker service create and docker service update
- How I did it
By modifying container service to accept the option as well as adding a flag to the CLI
- How to test it
Compile this PR and copy the CLI binary to a running moby dev shell using moby/moby#47950
- Description for the changelog