Skip to content
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

cmd: generate: add --linux-namespace-* family of flags #288

Merged
merged 4 commits into from
Feb 1, 2017

Conversation

cyphar
Copy link
Member

@cyphar cyphar commented Dec 12, 2016

This allows users to modify what namespaces are used by a container.

Signed-off-by: Aleksa Sarai [email protected]

@cyphar cyphar force-pushed the namespace-flags branch 2 times, most recently from 870cde8 to 081b841 Compare December 12, 2016 11:20
@mrunalp
Copy link
Contributor

mrunalp commented Dec 12, 2016

LGTM

Approved with PullApprove

@mrunalp
Copy link
Contributor

mrunalp commented Dec 12, 2016

@Mashimiao @liangchenye @wking PTAL

@Mashimiao
Copy link

we already have --user --memory --ipc --mount --network --pid --uts to add namespaces, I think --linux-namespace-add conflicts with them.

@cyphar
Copy link
Member Author

cyphar commented Dec 13, 2016

@Mashimiao Yeah, you're right. However, we should probably have something like --linux-namespace-remove and --linux-namespace-remove-all.

@Mashimiao
Copy link

If the value of current namespace options is host, we will remove existing namespace. For example,
if we set --uts=host, we will remove existing uts namespace from config.
But I think that --linux-namespace-* is clear for users to understand and use.
How about removing namespace options like --uts, --user, --pid, etc? @mrunalp @liangchenye @wking

@wking
Copy link
Contributor

wking commented Dec 13, 2016 via email

@cyphar
Copy link
Member Author

cyphar commented Dec 21, 2016

I've updated this PR so that it removes the old namespace flags, and added documentation changes for them.

/cc @Mashimiao @mrunalp

@Mashimiao
Copy link

@cyphar please also update completions/bash file

@cyphar
Copy link
Member Author

cyphar commented Dec 21, 2016

@Mashimiao Done. There were a few other flags not included or incorrectly classified, so I've fixed it up.

Copy link
Contributor

@wking wking left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One nit and one caveat, but otherwise looks good to me :).

@@ -608,6 +613,18 @@ func parseRlimit(rlimit string) (string, uint64, uint64, error) {
return parts[0], uint64(hard), uint64(soft), nil
}

func parseNamespace(ns string) (string, string, error) {
parts := strings.Split(ns, ":")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SplitSplitN? Linux allows paths to contain colons.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

if len(uidMaps) > 0 || len(gidMaps) > 0 {
needsNewUser = true
g.AddOrReplaceLinuxNamespace("user", "")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will silently create an invalid config with --uidmappings=… --linux-namespace-add=user:foo, because the resulting config with call for tweaking a joined namespace. I'm pro-tweaking though, and we're already doing something silent about this case, so I'm ok with that ;). Folks who want to ensure validity can pass their final config through to validate as a separate step.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it'll generate an invalid config, because the --linux-namespace-add handling is done afterwards and so the user entry will be replaced.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, sorry, it will generate an invalid config, but the user asked us to generate it...

@wking
Copy link
Contributor

wking commented Dec 22, 2016 via email

@@ -608,6 +613,18 @@ func parseRlimit(rlimit string) (string, uint64, uint64, error) {
return parts[0], uint64(hard), uint64(soft), nil
}

func parseNamespace(ns string) (string, string, error) {
parts := strings.SplitN(ns, ":", 2)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't check parts[0], then :testpat will also be a valid value. Though user set it, I think we should warn user it's invalid, as I did in #292

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can validate it against the spec's whitelist. But I'm fine punting validation to a post-generate call (for callers who care). Maybe they intend to fix the values in post-processing.

Copy link
Member Author

@cyphar cyphar Dec 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed it to check parts[0]. The whitelist checking should be done in the generate library (IMO), and I'll punt it for now. I mean, we don't actually have tests for generate at all -- so maybe we should do that first? 😉

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what kind of tests?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There aren't any unit tests or integration tests for oci-runtime-tool. We should probably add some. Also, this tool isn't versioned which makes packaging annoying.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More importantly, as far as I can tell there's no tests of the validation -- which is quite worrying.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should add unit tests. unit tests for validation already in #273

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd floated some sharness stubs for testing in #180. Happy to rebase if there is renewed interest.

return parts[0], parts[1], nil
}

panic("should not be reached")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I don't like this. the panic error message does not tell user what's wrong clear.
I think we should give user clear error message and they don't have to hack code to find out what's wrong

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a panic because you literally cannot reach that part of the code. len(parts) can only have a length of 0, 1, and 2 and all cases have been handled. If I remove the panic you get errors about no return statement, even though you cannot reach that line.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can make the function longer to make you happy if you really want.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All cases of len(parts) are handled, so we will never reach panic. In my opinion, panic here make no sense.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you want to return an error even though the actual line will never be hit? From my experience, people use panic in these situations because it's more clear that if you ever hit that line it's a programming error (not something that should happen normally).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I mean do not need panic or return here. Just remove this panic, because it will never be reached

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go won't compile that program, which is why I added panic... Go isn't clever enough to know that the line won't be hit.

Copy link
Member Author

@cyphar cyphar Dec 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mention this above

If I remove the panic you get errors about no return statement, even though you cannot reach that line.

go build -tags "" -o oci-runtime-tool ./cmd/oci-runtime-tool
# runtime-tools/cmd/oci-runtime-tool
../../.local/src/runtime-tools/cmd/oci-runtime-tool/generate.go:629: missing return at end of function

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this?
func parseNamespace(ns string) (string, string, error) {
var nsType, nsPath string
parts := strings.SplitN(ns, ":", 2)
if len(parts) == 0 || parts[0] == "" {
return "", "", fmt.Errorf("invalid namespace value: %s", ns)
}

switch len(parts) {
case 1:
	nsType, nsPath = parts[0], ""
case 2:
	nsType, nsPath = parts[0], parts[1]
}

return nsType, nsPath, nil

}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the panic. PTAL.

@Mashimiao
Copy link

Mashimiao commented Dec 24, 2016

LGTM

Approved with PullApprove

}
}

if context.IsSet("linux-namespace-remove-all") {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be context.Bool("linux-namespace-remove-all"). If not, when linux-namespace-remove-all is false, ClearLinuxNamespaces function will still be called.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was copying what --rlimits-remove-all and --seccomp-remove-all (the only other flags of this form) do. I don't disagree, it's just that the problem exists with other flags too.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I just pushed a PR to fix it

This allows users to modify what namespaces are used by a container.

Signed-off-by: Aleksa Sarai <[email protected]>
--uts, --user and the other flags are not properly namespaced or
extensible, so remove them in favour of the new --linux-namespace-*
family of flags.

Signed-off-by: Aleksa Sarai <[email protected]>
This is generated from "oci-runtime-tool generate -h".

Signed-off-by: Aleksa Sarai <[email protected]>
@Mashimiao
Copy link

Mashimiao commented Dec 30, 2016

LGTM

Approved with PullApprove

@cyphar
Copy link
Member Author

cyphar commented Feb 1, 2017

/ping @opencontainers/runtime-tools-maintainers

@dqminh
Copy link
Contributor

dqminh commented Feb 1, 2017

LGTM

Approved with PullApprove

@dqminh dqminh merged commit 2d92f65 into opencontainers:master Feb 1, 2017
@cyphar cyphar deleted the namespace-flags branch February 1, 2017 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants