-
Notifications
You must be signed in to change notification settings - Fork 593
config: Make 'process.args' optional #620
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
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’. |
runtime.md
Outdated
| 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
| 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
startwill 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. |
config.md
Outdated
| * **`args`** (array of strings, REQUIRED) with similar semantics to [IEEE Std 1003.1-2001 `execvp`'s *argv*][ieee-1003.1-2001-xsh-exec]. | ||
| * **`args`** (array of strings, OPTIONAL) with similar semantics to [IEEE Std 1003.1-2001 `execvp`'s *argv*][ieee-1003.1-2001-xsh-exec]. | ||
| 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,deletewithout callingstart). For folks who expect to do that, theres no reason to defineprocess.args`.The main point of #489 without the surrounding cleanup, since most of the cleanup has since landed via:
processas 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.argsin 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, sostartcalls will fail”. But I'd rather not have this spec require dummyprocess.argsfrom folks who will never callstart.