-
Notifications
You must be signed in to change notification settings - Fork 554
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
config: Make 'process.args' optional #620
Conversation
Well, I think if
Then it should make more sense to keep it REQUIRED.
If the user code will never be started, you can specify anything in so -1 on this. |
On Mon, Nov 14, 2016 at 01:09:22AM -0800, zhangwei_cs wrote:
That's not legal, because we currently require the executable to exist
I'm fine having validation tooling that warns (or errors, as long as {"process": {"args": ["/"], …}, …} for folks who will never call ‘start’. |
@@ -103,6 +103,7 @@ This operation MUST generate an error if it is not provided the container ID. | |||
Attempting to start a container that does not exist MUST generate an error. | |||
Attempting to start an already started container MUST have no effect on the container and MUST generate an error. | |||
This operation MUST run the user-specified code as specified by [`process`](config.md#process-configuration). | |||
If `process.args` was not configured, the runtime MUST generate an 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.
If the process.args
array is not specified or if the user-specified code cannot be found or started the runtime MUST generate an 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.
I'd rather not make that change. The execution will usually be by a call to execve(2)
or similar, and while that returns errors like ENOENT
, ENOEXEC
, etc. on failure, there's no way to get it to return something on success (because by that point the process will be running the user-specified program). And start
is just signalling an external process to execute code (e.g. see opencontainers/runc#886, where the start
process drains a fifo to trigger an execve
in the container process). So I don't see a way to block on potential execve
errors in the start
process short of ptrace(2)
monitoring, and that seems like too high a cost.
I'd rather have start
error out if it failed to trigger the start attempt (which the container process can confirm with “start received. I'm about to execve
, wish me luck”). Folks who are curious about whether that execve
succeeded can either ptrace
the container process themselves, or monitor state
, etc.
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.
Yeah, I wasn't looking for failures in the process started, I'm looking for failure to specify a runnable executable as arg0 of the process.args array. At least change it to:
If the process.args array does not at least include a first argument specifying the user-specified code the runtime MUST generate an 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.
Otherwise we need some sort of default.. description. No?
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 sounds like a subset of the current process.args
requirements, so it would fall under the “MAY validate” portion of create
. Do we need a “MUST validate process
” (or just process.args
?) clause in start
? My personal preference would be to leave validation up to the caller, who can run bundle-validation tools whenever they want. I'm happy to make that an explicit part of the start
spec, if folks think it would help. I'll grudgingly make a MUST-validate-whatever clause a part of the start
spec if that's the maintainer consensus ;).
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.
Otherwise we need some sort of default.. description.
With optional validation, runtimes that choose not to validate in start
will have this sort of miss-configuration result in the same sort of error-workflow that applies to execve
errors. I don't see a need for a default, and am not sure what sort of default you'd pick in any 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.
Yeah I didn't see a good default either... certainly would not have picked "/" :)
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 thought the point was start does not have to be called.
Yes.
… thus we only have this MUST when start is called.
That's what I was going for with an optional process.args
which still contains a MUST for an initial argument. That requirement (if process.args
is set, it MUST contain that leading entry) applies to all configs, not just when start
is called.
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.
changing is not configured
to is not set
is more understandable to me.
also maybe we should use the same set of phrases above ? maybe This operation MUST generate an error if process.args is not set
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.
maybe
This operation MUST generate an error if process.args is not set
Done (and rebased onto master) with 35ee63b → 7071706, although I used “was” instead of “is” because what matters is what was in the configuration at create
-time.
35ee63b
to
7071706
Compare
@@ -103,6 +103,7 @@ This operation MUST generate an error if it is not provided the container ID. | |||
Attempting to start a container that does not exist MUST generate an error. | |||
Attempting to start an already started container MUST have no effect on the container and MUST generate an error. | |||
This operation MUST run the user-specified program as specified by [`process`](config.md#process). | |||
This operation MUST generate an error if `process.args` was not set. |
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 process.args array is currently "OPTIONAL", not REQUIRED. So if it's optional we need to explain why/when its REQUIRED. I know you know why, but it does not explicitly say why / when. The MUST requirement being in the START command paragraph "implies" that the process.args array (first element) is REQUIRED only when START is used but is not explicit or explained. The word "set" does not express explicitly what you mean. I only mention this because I believe MUST language should only have one interpretation.
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.
After some discussion on IRC, @mikebrow recommended the following addition to the process.args
docs:
When start is used process.args is no longer OPTIONAL and MUST be set.
There's also a similar conditional requirement in the device spec, but “REQUIRED unless you won't call start
” and “OPTIONAL unless you'll call start
in which case it's REQUIRED” both feel too awkward.
With 7071706 → e45ddba I've added:
When
start
will be called, this property is REQUIRED.
which gets the cross-reference to the start
command. It replaces @mikebrow's “is no longer OPTIONAL and MUST be set” with “is REQUIRED”, because I like “REQUIRED” better than “MUST be set”. I think “is no longer OPTIONAL” is fairly clear from the context, but I'm ok adding that back in if folks feel like it's necessary. And I've replaced “is used” with “will be called” because you need to set this field at create
time in order to use it when start
is called.
7071706
to
e45ddba
Compare
Looks good to me. |
This specification extends the IEEE standard in that at least one entry is REQUIRED, and that entry is used with the same semantics as `execvp`'s *file*. | ||
When [`start`](runtime.md#start) will be called, this property is REQUIRED. |
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 property is required when start is called
seems better for me.
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 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.
when works..
@opencontainers/runtime-spec-maintainers PTAL |
Since be59415 (Split create and start, 2016-04-01, opencontainers#384), it's possible for a container process to never execute user-specified code (e.g. you can call 'create', 'kill', 'delete' without calling 'start'). For folks who expect to do that, there's no reason to define process.args. The only other process property required for all platforms is 'cwd', but the runtime's idler code isn't specified in sufficient detail for the configuration author to have an opinion about what its working directory should be. On Linux and Solaris, 'user' is also required for 'uid' and 'gid'. My preferred approach here is to make those optional and define defaults [1,2]: If unset, the runtime will not attempt to manipulate the user ID (e.g. not calling setuid(2) or similar). But the maintainer consensus is that they want those to be explicitly required properties [3,4,5]. With the current spec, one option could be to make process optional (with the idler's working directory unspecified) for OSes besides Linux and Solaris. On Windows, username is optional, but it's not clear how intentional that was [6]. [1]: opencontainers#417 (comment) [2]: https://groups.google.com/a/opencontainers.org/forum/#!topic/dev/DWdystx5X3A Subject: Exposing platform defaults Date: Thu, 14 Jan 2016 15:36:26 -0800 Message-ID: <[email protected]> [3]: http://ircbot.wl.linuxfoundation.org/meetings/opencontainers/2016/opencontainers.2016-05-04-17.00.log.html#l-44 [4]: opencontainers#417 (comment) [5]: opencontainers#417 (comment) [6]: opencontainers#618 Signed-off-by: W. Trevor King <[email protected]>
e45ddba
to
bebdd29
Compare
Now that d43fc42 (config-linux: Lift no-tweaking namespace restriction, 2017-01-11, opencontainers#649) allows us to get into this sort of situation. This sort of ownership may also apply to other resources (cgroups?), but we can handle them in follow-up commits. Also drop "Configuration" from the root header. Everything in that file is a configuration. container-namespace3 (instead of container-namespace) supports the single-page, Pandoc-generated file (see e7be40f, Cleanup the spec a bit to remove WG/git text that's not really part of the spec, 2016-11-14, opencontainers#626). Using an informative suggestion was recommended by Dao Quang Minh [1]. I've made the config JSON as small as possible while keeping it valid, but there's still an unfortunate amount of boilerplate there. There is in-flight work to let us at least drop process.args [2]. [1]: opencontainers#651 [2]: opencontainers#620 Signed-off-by: W. Trevor King <[email protected]>
Now that d43fc42 (config-linux: Lift no-tweaking namespace restriction, 2017-01-11, opencontainers#649) allows us to get into this sort of situation. This sort of ownership may also apply to other resources (cgroups?), but we can handle them in follow-up commits. Using an informative suggestion was recommended by Dao Quang Minh [1]. I've made the config JSON as small as possible while keeping it valid, but there's still an unfortunate amount of boilerplate there. There is in-flight work to let us at least drop process.args [2]. The new mount namespace in the UTS example avoids pivoting the host namespace's root. Also drop "Configuration" from the root header. Everything in that file is a configuration. container-namespace3 (instead of container-namespace) supports the single-page, Pandoc-generated file (see e7be40f, Cleanup the spec a bit to remove WG/git text that's not really part of the spec, 2016-11-14, opencontainers#626). [1]: opencontainers#651 [2]: opencontainers#620 Signed-off-by: W. Trevor King <[email protected]>
If we want to be pedantic basically all of the process is not needed if you don't specify args or do start. |
But there are affects to not specifying However the |
Overall, if we want to do this, I would just make process optional and be done with it. The init is always launched as root or whatever the userns mapping is and we don't change. It would be a fully privileged process in the container however and there is not a good way around that as we need to retain the caps for the finalizing step of the container. Its not really a use case that we want to support but it can be done for advanced users that want to fire off many execs without fully creating a container and it up to the runtime and implementer to secure things, we cannot guarantee anything. What do the other maintainers think? |
After a brief chat with maintainers in IRC, we are going to close this specific modification. Just having args as optional makes no sense at all. Either the entire process section should be optional for what you want to do or it should be left as is but this change is not ideal for any usecase. |
Based on IRC discussion today (times in PST) [1]: 11:36 < crosbymichael> just take a step back and think about it. you have a process object in the spec. its a single object defining what to run. How do you run a process? you exec its args. From the spec pov its an atomic operation. in between create and start its not running the users code and is left up to the runtime. you either have a process defined by the spec and its created as an operation in the container on start or your dont. This means that the caller has no way to set the user/cwd/capabilities/… of the runtime's container process between 'create' and 'start'. You could avoid that limitation by requiring all process properties *except* process.args be applied at create-time, but my attempt to make process.args optional (which would have allowed that interpretation without burdening callers who never intended to call 'start') was rejected in favor of this all-or-nothing approach to 'process' handling [2]. [1]: http://ircbot.wl.linuxfoundation.org/eavesdrop/%23opencontainers/%23opencontainers.2017-02-27.log.html#t2017-02-27T19:35:35 [2]: opencontainers#620 (comment) Signed-off-by: W. Trevor King <[email protected]>
Based on IRC discussion today (times in PST) [1]: 11:36 < crosbymichael> just take a step back and think about it. you have a process object in the spec. its a single object defining what to run. How do you run a process? you exec its args. From the spec pov its an atomic operation. in between create and start its not running the users code and is left up to the runtime. you either have a process defined by the spec and its created as an operation in the container on start or your dont. With the previous wording, it was unclear how large a hole we were poking with "the user-specified program MUST NOT be run at this time". This commit removes that ambiguous wording and replaces it with an explicit reference to 'process.args'. It makes it clear that everything outside of 'process' MUST happen at create-time. And it leaves all of 'process' except for 'process.args' up to the implementation. This means that the caller has no reliable way to set the user/cwd/capabilities/… of the runtime's container process between 'create' and 'start'. You could avoid that limitation by requiring all process properties *except* process.args be applied at create-time, but my attempt to make process.args optional (which would have allowed that interpretation without burdening callers who never intended to call 'start') was rejected in favor of this all-or-nothing approach to 'process' handling [2]. [1]: http://ircbot.wl.linuxfoundation.org/eavesdrop/%23opencontainers/%23opencontainers.2017-02-27.log.html#t2017-02-27T19:35:35 [2]: opencontainers#620 (comment) Signed-off-by: W. Trevor King <[email protected]>
Based on IRC discussion today (times in PST) [1]: 11:36 < crosbymichael> just take a step back and think about it. you have a process object in the spec. its a single object defining what to run. How do you run a process? you exec its args. From the spec pov its an atomic operation. in between create and start its not running the users code and is left up to the runtime. you either have a process defined by the spec and its created as an operation in the container on start or your dont. With the previous wording, it was unclear how large a hole we were poking with "the user-specified program MUST NOT be run at this time". This commit removes that ambiguous wording and replaces it with an explicit reference to 'process.args'. It makes it clear that everything outside of 'process' MUST happen at create-time. And it leaves all of 'process' except for 'process.args' up to the implementation. This means that the caller has no reliable way to set the user/cwd/capabilities/… of the runtime's container process between 'create' and 'start'. You could avoid that limitation by requiring all process properties *except* process.args be applied at create-time, but my attempt to make process.args optional (which would have allowed that interpretation without burdening callers who never intended to call 'start') was rejected in favor of this all-or-nothing approach to 'process' handling [2]. [1]: http://ircbot.wl.linuxfoundation.org/eavesdrop/%23opencontainers/%23opencontainers.2017-02-27.log.html#t2017-02-27T19:35:35 [2]: opencontainers#620 (comment) Signed-off-by: W. Trevor King <[email protected]>
Based on IRC discussion today (times in PST) [1]: 11:36 < crosbymichael> just take a step back and think about it. you have a process object in the spec. its a single object defining what to run. How do you run a process? you exec its args. From the spec pov its an atomic operation. in between create and start its not running the users code and is left up to the runtime. you either have a process defined by the spec and its created as an operation in the container on start or your dont. With the previous wording, it was unclear how large a hole we were poking with "the user-specified program MUST NOT be run at this time". This commit removes that ambiguous wording and replaces it with an explicit reference to 'process.args'. It makes it clear that everything outside of 'process' MUST happen at create-time. And it leaves all of 'process' except for 'process.args' up to the implementation. This means that the caller has no reliable way to set the user/cwd/capabilities/… of the runtime's container process between 'create' and 'start'. You could avoid that limitation by requiring all process properties *except* process.args be applied at create-time, but my attempt to make process.args optional (which would have allowed that interpretation without burdening callers who never intended to call 'start') was rejected in favor of this all-or-nothing approach to 'process' handling [2]. [1]: http://ircbot.wl.linuxfoundation.org/eavesdrop/%23opencontainers/%23opencontainers.2017-02-27.log.html#t2017-02-27T19:35:35 [2]: opencontainers#620 (comment) Signed-off-by: W. Trevor King <[email protected]>
Since #384, it's possible for a container process to never execute user-specified code (e.g. you can call
create
,kill
,delete
without callingstart
). For folks who expect to do that, theres no reason to define
process.args`.The main point of #489 without the surrounding cleanup, since most of the cleanup has since landed via:
process
as required from config: Synchronize comments between Markdown and Go #525.There was some negative review of this change in #489, although @mrunalp acknowledged support for the “never calling
start
” workflow. If there is a maintainer consensus around that workflow being supported, requiringprocess.args
in all cases seems like needless hoop-jumping. I'm fine with validation tooling warning users “you might have forgotten to put something meaningful inprocess.args
, sostart
calls will fail”. But I'd rather not have this spec require dummyprocess.args
from folks who will never callstart
.