-
Notifications
You must be signed in to change notification settings - Fork 2k
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
--isolation for setting swarm service isolation mode #426
Conversation
Codecov Report
@@ Coverage Diff @@
## master #426 +/- ##
==========================================
+ Coverage 50.75% 51.28% +0.53%
==========================================
Files 216 216
Lines 17730 17743 +13
==========================================
+ Hits 8998 9099 +101
+ Misses 8276 8175 -101
- Partials 456 469 +13 |
a81a3fe
to
9843598
Compare
@simonferquel can you link PRs in swarmkit and moby related to this feature ? 👼 |
537ba2f
to
83faf7d
Compare
4aa7e53
to
27b818a
Compare
PR on Swarmkit: moby/swarmkit#2342 |
moby/moby#34424 was merged, so this PR can be worked on again; @simonferquel can you do a rebase/revendor? |
92b49da
to
ee86d46
Compare
Requires moby/moby#35382. in the mean time i'll add tests to improve coverage (mainly on update) |
a85b1a4
to
958ab3b
Compare
cli/command/service/opts_test.go
Outdated
@@ -4,6 +4,8 @@ import ( | |||
"testing" | |||
"time" | |||
|
|||
"github.com/stretchr/testify/require" | |||
|
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.
nit: This extra newline can be removed
cli/command/service/update.go
Outdated
err := o.Set(val) | ||
if err != nil { | ||
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.
You don't need to create a new isolationOpts
struct here. Value
is that struct, you just have to cast it (like the functions above).
assert.Equal(t, container.IsolationProcess, spec.TaskTemplate.ContainerSpec.Isolation) | ||
} | ||
|
||
func TestUpdateIsolationInvalid(t *testing.T) { |
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 think this test needs to call updateService()
otherwise it's only testing isolationOpt
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, makes sense, I'll remove the test as opts is already tested and updateService won't be called if flags parsing fails
cli/compose/convert/service.go
Outdated
@@ -122,6 +122,11 @@ func Service( | |||
} | |||
} | |||
|
|||
isolation := container.Isolation(service.Isolation) | |||
if !isolation.IsDefault() && !isolation.IsHyperV() && !isolation.IsProcess() { | |||
return swarm.ServiceSpec{}, fmt.Errorf("Unsupported isolation %s. Valid values are %s, %s, %s", isolation, container.IsolationDefault, container.IsolationProcess, container.IsolationHyperV) |
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 already validated by the isolationOpt
we shouldn't need to do it again here, right?
The validation should be handled by the flags/value types so that any value stored in the opt is valid to send to the API.
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 this case, the source is not an isolationOpt flag, but a compose-file field (which is of type string)
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.
Oh, I missed that! For the compose file we do the validation as part of the types/loading. Could this validation be moved there?
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.
Did not see that, thank! I changed validation by typing the isolation field in service type to container.Isolation, and introduced a transformValidation function at loading time (that does the validation). Also added a parsing test for invalid isolation.
cli/compose/convert/service_test.go
Outdated
@@ -372,3 +372,14 @@ func TestConvertUpdateConfigOrder(t *testing.T) { | |||
}) | |||
assert.Equal(t, updateConfig.Order, "stop-first") | |||
} | |||
|
|||
func TestIsolation(t *testing.T) { |
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.
s/TestIsolation/TestServiceConvertsIsolation/
cli/compose/convert/service_test.go
Outdated
result, err := Service("1.32", Namespace{name: "foo"}, src, nil, nil, nil, nil) | ||
if err != nil { | ||
t.Fatal(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.
require.NoError(t, err)
?
cli/command/service/opts.go
Outdated
o.value = &tv | ||
return nil | ||
} | ||
return fmt.Errorf("Unknown isolation mode %s. Valid values are %v, %v, %v", value, container.IsolationDefault, container.IsolationProcess, container.IsolationHyperV) |
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.
Ideally, this would be checked by the daemon, instead of the client. Do we have a similar check already daemon-side?
Trying to delegate validation to the daemon as much as possible, because (supported) options can differ, depending on the version of the daemon, and we should not have to keep track of that in the client.
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 point. Actually it is already validated daemon-side with different validation logic on Linux (which only supports empty or default isolation) and windows (that also supports process and hyperv). I'll remove that client-side validation alltogether, and I'll make sure daemon-side errors are surfaced in a good way to the user
This will also need;
|
Also opened a moby bump in #679, which should bring in the required changes |
@thaJeztah sorry for the delay, it has been quite a busy time lately... |
Thanks! |
cli/command/service/opts.go
Outdated
o.source = value | ||
tv := container.Isolation(value) | ||
o.value = &tv | ||
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.
This never returns an error; is the error to satisfy an interface?
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, it is the flag.Value interface.
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.
Check ✅
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.
one question, but otherwise I think this is ready to go after squashing
46246fb
to
5a009e8
Compare
Squashed & rebased |
cli/compose/loader/loader.go
Outdated
if !ok { | ||
return value, errors.Errorf("invalid type %T for isolation", value) | ||
} | ||
return container.Isolation(strings.ToLower(str)), 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.
Missed this in my previous review; can you remove the strings.ToLower()
here as well?
5a009e8
to
735ca51
Compare
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.
LGTM, thanks!
ping @vdemeester @dnephin 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.
Just one small issue with the Compose support, otherwise looks good
cli/command/service/opts.go
Outdated
} | ||
|
||
func (o *isolationOpts) Type() string { | ||
return "isolation" |
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 type is what gets reported in the help text. I wonder if string
would be more helpful to users.
cli/compose/types/types.go
Outdated
@@ -125,7 +127,8 @@ type ServiceConfig struct { | |||
Ulimits map[string]*UlimitsConfig | |||
User string | |||
Volumes []ServiceVolumeConfig | |||
WorkingDir string `mapstructure:"working_dir"` | |||
WorkingDir string `mapstructure:"working_dir"` | |||
Isolation container.Isolation `mapstructure:"isolation"` |
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 think this should be string
. Everywhere else we accept plain types and do the convert to swarm/api types in convert. This helps keep the compose config packages decoupled from the api.
I believe this change will remove the need for the custom transform in loader.go as well.
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 guess this was here previously because of validation. I should have looked closer when I was commenting the first time. Sorry about that.
735ca51
to
2386b2e
Compare
@dnephin I just reverted service options to use plain string type for isolation, and modified compose types to remove all traces of validation (removing transformIsolation). Should be ok now. |
@@ -42,6 +42,7 @@ Options: | |||
--help Print usage | |||
--host list Set one or more custom host-to-IP mappings (host:ip) | |||
--hostname string Container hostname | |||
--isolation isolation Service container isolation mode |
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 should be "string" now then? (same for the other usage output)
2386b2e
to
e4d3b1d
Compare
Good catch @thaJeztah , fixed :) |
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.
still LGTM
Oh, actually; dang, test is failing:
|
@@ -0,0 +1,544 @@ | |||
{ |
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.
Wondering what we did previous times when adding a new version; perhaps it's cleaner if there were two commits; one that adds a "pristine" compose 3.5 (exact copy of 3.4), and one commit that adds your changes
e4d3b1d
to
e8215fb
Compare
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
e8215fb
to
47cf2ea
Compare
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.
LGTM 🐮
🍪 |
fixes #414
- What I did
Added --isolation to service create/update and to compose files, to bypass default isolation mode on the host.
- How I did it
Updated dependencies to moby/moby and swarmkit (also had to depend on the logrus mega PR), added the flag in the service update/create cmd, passing the value accordingly
Updated the compose service struct and conversion to ServiceSpec accordingly
- How to verify it
Tests incoming
- Description for the changelog
Depends on #424