All of lore.kernel.org
 help / color / mirror / Atom feed
* [Buildroot] [PATCH v2] fs/oci: entrypoint and command are space-separated lists
@ 2022-05-13 13:17 yann.morin
  2022-05-15 20:22 ` Peter Korsgaard
  2022-05-29  8:34 ` Peter Korsgaard
  0 siblings, 2 replies; 3+ messages in thread
From: yann.morin @ 2022-05-13 13:17 UTC (permalink / raw)
  To: buildroot; +Cc: Yann E. MORIN, Sergio Prado, Matthew Weber

From: "Yann E. MORIN" <yann.morin@orange.com>

The prompt and variable name for the OCI "entrypoint arguments" are
somewhat incorrect. Indeed, they are in fact use to set the image
"command". Yet, using "command" would be confusing too, because the
interplay between entrypoint and command is tricky [0].

TL-DR; when both entrrypoint and command are set, command acts as
arguments passed to the entrypoint.

Additionally, we currently can only pass a single item as either
entrypoint or command. This precludes passing actual arguments to the
entrypoint, or passing multiple arguments as command.

For example:
    BR2_TARGET_ROOTFS_OCI_ENTRYPOINT="/bin/tini -g -p SIGTERM --"
    BR2_TARGET_ROOTFS_OCI_ENTRYPOINT_ARGS="/usr/bin/env sh"

generates an images with (only relevant fileds are included below):

    {
        "config": {
            "Entrypoint": [ "/bin/tini -g -p SIGTERM --" ],
            "Cmd": [ "/usr/bin/env sh" ]
        }
    }

This is obviously incorrect, and not what one would expect:

    {
        "config": {
            "Entrypoint": [ "/bin/tini", "-g", "-p", "SIGTERM", "--" ],
            "Cmd": [ "/usr/bin/env", "sh" ]
        }
    }

However, some people do want to be able to pass an actual shell
scriptlet as a command, such as:

    {
        "config": {
            "Entrypoint": [ "/bin/sh", "-c" ],
            "Cmd": [ "my shell logic goes here" ]
        }
    }

Handling both is obviously conflicting: we can't both split-on-spaces
and not-split-on-spaces at the same time...

So, we fix that in tow ways:

  - make the current _OCI_ENTRYPOINT_ARGS a legacy option, and introduce
    the new _OCI_CMD option with different semantics (see below) and an
    appropriate prompt;

  - we interpret both _OCI_ENTRYPOINT and _OCI_CMD as shell strings,
    which we subject to the usual shell quoting [1] and token
    recognition [2];

Since _OCI_ENTRYPOINT_ARGS used to be interpreted as a single string, we
can't easily change its meaning to be a space-separated list, as that
would break existing setups, which is the reason we make it legacy and
introduce a new option.

Ideally, we would like to default the new option _OCI_CMD to be the
quoted value of the previous _OCI_ENTRYPOINT_ARGS, but this is not
possible in Kconfig. Still, users that had a _OCI_ENTRYPOINT_ARGS set
will now get an early build error, and can still detect they need to do
something about it.

As for _OCI_ENTRYPOINT, it does not make much sense to support both
cases. Indeed, withoput splitting on spaces, we'd end up with an
entrypoint that would hava single item:

    {
        "config": {
            "entrypoint: [ "some string with some spaces" ]
        }
    }

which in this case would try to execute the program which name is
actually "some string with some spaces", so we do not expect that
existing entrypoints are set with any space in them, and so the new
behaviour, unlike for _OCI_ENTRYPOINT_ARGS vs. _OCI_CMD, is compatible
with existing configurations, and so we do not need to make it a legacy
option and introduce a new one.

[0] https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact
[1] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02
[2] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03

Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
Cc: Sergio Prado <sergio.prado@e-labworks.com>
Cc: Matthew Weber <matthew.weber@collins.com>

---
Changes v1 -> v2:
  - drop _OCI_ENTRYPOINT_ARGS and replace with _OCI_CMD
  - accept values that have shell escapes and quotes, and spaces
---
 Config.in.legacy | 19 +++++++++++++++++++
 fs/oci/Config.in | 22 +++++++++++++++++++---
 fs/oci/oci.mk    | 28 +++++++++++++++++-----------
 3 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/Config.in.legacy b/Config.in.legacy
index 48c5ebb81e..8bbefc5ecd 100644
--- a/Config.in.legacy
+++ b/Config.in.legacy
@@ -146,6 +146,25 @@ endif
 
 comment "Legacy options removed in 2022.02"
 
+config BR2_TARGET_ROOTFS_OCI_ENTRYPOINT_ARGS
+	string "entrypoint argumetns has been changed as command"
+	help
+	  The OCI image BR2_TARGET_ROOTFS_OCI_ENTRYPOINT_ARGS option has
+	  been renamed to BR2_TARGET_ROOTFS_OCI_CMD to better reflect its
+	  relation to the actual 'command' of the OCI image.
+
+	  The new semantic for BR2_TARGET_ROOTFS_OCI_CMD is slightly
+	  differnt in relation to how it is interpreted, so be sure to
+	  review the help entry for it.
+
+	  Due to this breaking change, the old value here could not be
+	  set to the new variable.
+
+config BR2_TARGET_ROOTFS_OCI_ENTRYPOINT_ARGS_WRAP
+	bool
+	default y if BR2_TARGET_ROOTFS_OCI_ENTRYPOINT_ARGS != ""
+	select BR2_LEGACY
+
 config BR2_PACKAGE_LIBCURL_LIBNSS
 	bool "libcurl NSS removed"
 	select BR2_LEGACY
diff --git a/fs/oci/Config.in b/fs/oci/Config.in
index 8f36c91c8f..5e7aff282f 100644
--- a/fs/oci/Config.in
+++ b/fs/oci/Config.in
@@ -42,10 +42,26 @@ config BR2_TARGET_ROOTFS_OCI_ENTRYPOINT
 	help
 	  Command to execute when the container starts.
 
-config BR2_TARGET_ROOTFS_OCI_ENTRYPOINT_ARGS
-	string "entrypoint arguments"
+	  Spaces must be quoted or escaped, like for a shell string:
+	    /usr/bin/env sh -c
+	    /bin/my-init --some-option "1 2 3 4" some\ arg --
+
+	  See the Docker documentation on how entrypoint and command
+	  interact together:
+	    https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact
+
+config BR2_TARGET_ROOTFS_OCI_CMD
+	string "command (or entrypoint arguments)"
 	help
-	  Default arguments to the entrypoint of the container.
+	  Default command, or entrypoint arguments, of the container.
+
+	  Spaces must be quoted or escaped, like for a shell string:
+	    "your shell scriptlet"
+	    /usr/bin/env sh
+
+	  See the Docker documentation on how entrypoint and command
+	  interact together:
+	    https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact
 
 config BR2_TARGET_ROOTFS_OCI_WORKDIR
 	string "working directory"
diff --git a/fs/oci/oci.mk b/fs/oci/oci.mk
index aa81920d36..4458cf8ef9 100644
--- a/fs/oci/oci.mk
+++ b/fs/oci/oci.mk
@@ -12,17 +12,23 @@ OCI_SLOCI_IMAGE_OPTS = --arch $(GO_GOARCH)
 # architecture variant (typically used only for arm)
 OCI_SLOCI_IMAGE_OPTS += $(and $(GO_GOARM),--arch-variant v$(GO_GOARM))
 
-# entrypoint
-OCI_ENTRYPOINT = $(call qstrip,$(BR2_TARGET_ROOTFS_OCI_ENTRYPOINT))
-ifneq ($(OCI_ENTRYPOINT),)
-OCI_SLOCI_IMAGE_OPTS += --entrypoint "$(OCI_ENTRYPOINT)"
-endif
-
-# entrypoint arguments
-OCI_ENTRYPOINT_ARGS = $(call qstrip,$(BR2_TARGET_ROOTFS_OCI_ENTRYPOINT_ARGS))
-ifneq ($(OCI_ENTRYPOINT_ARGS),)
-OCI_SLOCI_IMAGE_OPTS += --cmd "$(OCI_ENTRYPOINT_ARGS)"
-endif
+# entrypoint and command
+# Special treatment: both the entrypoint and arguments (aka command) are
+# a double-quoted, space-separated, escaped-double-quoted string, like:
+#     "foo \"1 2   3 4\" '  a b c d  ' bar\ buz"
+# which should be interpreted as a 4-item list (using single quotes to
+# delimit them and see leading/trailing spaces):
+#     'foo'
+#     '1 2   3 4'
+#     '  a b c d  '
+#     'bar buz'
+#
+# We use some trickery to have the shell properly expand this into a list
+# where each item is single-quoted and prefixed with the appropriate
+# option string:
+OCI_SLOCI_IMAGE_OPTS += \
+	$(shell eval printf -- "--entrypoint\ \'%s\'\ " $(BR2_TARGET_ROOTFS_OCI_ENTRYPOINT)) \
+	$(shell eval printf -- "--cmd\ \'%s\'\ " $(BR2_TARGET_ROOTFS_OCI_CMD))
 
 # author
 OCI_AUTHOR = $(call qstrip,$(BR2_TARGET_ROOTFS_OCI_AUTHOR))
-- 
2.25.1


_________________________________________________________________________________________________________________________

Ce message et ses pieces jointes peuvent contenir des informations confidentielles ou privilegiees et ne doivent donc
pas etre diffuses, exploites ou copies sans autorisation. Si vous avez recu ce message par erreur, veuillez le signaler
a l'expediteur et le detruire ainsi que les pieces jointes. Les messages electroniques etant susceptibles d'alteration,
Orange decline toute responsabilite si ce message a ete altere, deforme ou falsifie. Merci.

This message and its attachments may contain confidential or privileged information that may be protected by law;
they should not be distributed, used or copied without authorisation.
If you have received this email in error, please notify the sender and delete this message and its attachments.
As emails may be altered, Orange is not liable for messages that have been modified, changed or falsified.
Thank you.

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Buildroot] [PATCH v2] fs/oci: entrypoint and command are space-separated lists
  2022-05-13 13:17 [Buildroot] [PATCH v2] fs/oci: entrypoint and command are space-separated lists yann.morin
@ 2022-05-15 20:22 ` Peter Korsgaard
  2022-05-29  8:34 ` Peter Korsgaard
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Korsgaard @ 2022-05-15 20:22 UTC (permalink / raw)
  To: yann.morin; +Cc: Sergio Prado, Matthew Weber, buildroot

>>>>>   <yann.morin@orange.com> writes:

 > From: "Yann E. MORIN" <yann.morin@orange.com>
 > The prompt and variable name for the OCI "entrypoint arguments" are
 > somewhat incorrect. Indeed, they are in fact use to set the image
 > "command". Yet, using "command" would be confusing too, because the
 > interplay between entrypoint and command is tricky [0].

 > TL-DR; when both entrrypoint and command are set, command acts as
 > arguments passed to the entrypoint.

 > Additionally, we currently can only pass a single item as either
 > entrypoint or command. This precludes passing actual arguments to the
 > entrypoint, or passing multiple arguments as command.

 > For example:
 >     BR2_TARGET_ROOTFS_OCI_ENTRYPOINT="/bin/tini -g -p SIGTERM --"
 >     BR2_TARGET_ROOTFS_OCI_ENTRYPOINT_ARGS="/usr/bin/env sh"

 > generates an images with (only relevant fileds are included below):

 >     {
 >         "config": {
 >             "Entrypoint": [ "/bin/tini -g -p SIGTERM --" ],
 >             "Cmd": [ "/usr/bin/env sh" ]
 >         }
 >     }

 > This is obviously incorrect, and not what one would expect:

 >     {
 >         "config": {
 >             "Entrypoint": [ "/bin/tini", "-g", "-p", "SIGTERM", "--" ],
 >             "Cmd": [ "/usr/bin/env", "sh" ]
 >         }
 >     }

 > However, some people do want to be able to pass an actual shell
 > scriptlet as a command, such as:

 >     {
 >         "config": {
 >             "Entrypoint": [ "/bin/sh", "-c" ],
 >             "Cmd": [ "my shell logic goes here" ]
 >         }
 >     }

 > Handling both is obviously conflicting: we can't both split-on-spaces
 > and not-split-on-spaces at the same time...

 > So, we fix that in tow ways:

 >   - make the current _OCI_ENTRYPOINT_ARGS a legacy option, and introduce
 >     the new _OCI_CMD option with different semantics (see below) and an
 >     appropriate prompt;

 >   - we interpret both _OCI_ENTRYPOINT and _OCI_CMD as shell strings,
 >     which we subject to the usual shell quoting [1] and token
 >     recognition [2];

 > Since _OCI_ENTRYPOINT_ARGS used to be interpreted as a single string, we
 > can't easily change its meaning to be a space-separated list, as that
 > would break existing setups, which is the reason we make it legacy and
 > introduce a new option.

 > Ideally, we would like to default the new option _OCI_CMD to be the
 > quoted value of the previous _OCI_ENTRYPOINT_ARGS, but this is not
 > possible in Kconfig. Still, users that had a _OCI_ENTRYPOINT_ARGS set
 > will now get an early build error, and can still detect they need to do
 > something about it.

 > As for _OCI_ENTRYPOINT, it does not make much sense to support both
 > cases. Indeed, withoput splitting on spaces, we'd end up with an
 > entrypoint that would hava single item:

 >     {
 >         "config": {
 >             "entrypoint: [ "some string with some spaces" ]
 >         }
 >     }

 > which in this case would try to execute the program which name is
 > actually "some string with some spaces", so we do not expect that
 > existing entrypoints are set with any space in them, and so the new
 > behaviour, unlike for _OCI_ENTRYPOINT_ARGS vs. _OCI_CMD, is compatible
 > with existing configurations, and so we do not need to make it a legacy
 > option and introduce a new one.

 > [0] https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact
 > [1] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02
 > [2] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03

 > Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
 > Cc: Sergio Prado <sergio.prado@e-labworks.com>
 > Cc: Matthew Weber <matthew.weber@collins.com>

 > ---
 > Changes v1 -> v2:
 >   - drop _OCI_ENTRYPOINT_ARGS and replace with _OCI_CMD
 >   - accept values that have shell escapes and quotes, and spaces

 > +# entrypoint and command
 > +# Special treatment: both the entrypoint and arguments (aka command) are
 > +# a double-quoted, space-separated, escaped-double-quoted string, like:
 > +#     "foo \"1 2   3 4\" '  a b c d  ' bar\ buz"
 > +# which should be interpreted as a 4-item list (using single quotes to
 > +# delimit them and see leading/trailing spaces):
 > +#     'foo'
 > +#     '1 2   3 4'
 > +#     '  a b c d  '
 > +#     'bar buz'
 > +#
 > +# We use some trickery to have the shell properly expand this into a list
 > +# where each item is single-quoted and prefixed with the appropriate
 > +# option string:
 > +OCI_SLOCI_IMAGE_OPTS += \
 > +	$(shell eval printf -- "--entrypoint\ \'%s\'\ " $(BR2_TARGET_ROOTFS_OCI_ENTRYPOINT)) \
 > +	$(shell eval printf -- "--cmd\ \'%s\'\ " $(BR2_TARGET_ROOTFS_OCI_CMD))

Neat! Maybe we should add a test to ensure this doesn't break in the
future.

It still doesn't work for the case where the options contain references
to shell variables ($FOO) or shell commands ($(blih), `blah`), but it
didn't before either.

Committed, thanks.

-- 
Bye, Peter Korsgaard
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Buildroot] [PATCH v2] fs/oci: entrypoint and command are space-separated lists
  2022-05-13 13:17 [Buildroot] [PATCH v2] fs/oci: entrypoint and command are space-separated lists yann.morin
  2022-05-15 20:22 ` Peter Korsgaard
@ 2022-05-29  8:34 ` Peter Korsgaard
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Korsgaard @ 2022-05-29  8:34 UTC (permalink / raw)
  To: yann.morin; +Cc: Sergio Prado, Matthew Weber, buildroot

>>>>>   <yann.morin@orange.com> writes:

 > From: "Yann E. MORIN" <yann.morin@orange.com>
 > The prompt and variable name for the OCI "entrypoint arguments" are
 > somewhat incorrect. Indeed, they are in fact use to set the image
 > "command". Yet, using "command" would be confusing too, because the
 > interplay between entrypoint and command is tricky [0].

 > TL-DR; when both entrrypoint and command are set, command acts as
 > arguments passed to the entrypoint.

 > Additionally, we currently can only pass a single item as either
 > entrypoint or command. This precludes passing actual arguments to the
 > entrypoint, or passing multiple arguments as command.

 > For example:
 >     BR2_TARGET_ROOTFS_OCI_ENTRYPOINT="/bin/tini -g -p SIGTERM --"
 >     BR2_TARGET_ROOTFS_OCI_ENTRYPOINT_ARGS="/usr/bin/env sh"

 > generates an images with (only relevant fileds are included below):

 >     {
 >         "config": {
 >             "Entrypoint": [ "/bin/tini -g -p SIGTERM --" ],
 >             "Cmd": [ "/usr/bin/env sh" ]
 >         }
 >     }

 > This is obviously incorrect, and not what one would expect:

 >     {
 >         "config": {
 >             "Entrypoint": [ "/bin/tini", "-g", "-p", "SIGTERM", "--" ],
 >             "Cmd": [ "/usr/bin/env", "sh" ]
 >         }
 >     }

 > However, some people do want to be able to pass an actual shell
 > scriptlet as a command, such as:

 >     {
 >         "config": {
 >             "Entrypoint": [ "/bin/sh", "-c" ],
 >             "Cmd": [ "my shell logic goes here" ]
 >         }
 >     }

 > Handling both is obviously conflicting: we can't both split-on-spaces
 > and not-split-on-spaces at the same time...

 > So, we fix that in tow ways:

 >   - make the current _OCI_ENTRYPOINT_ARGS a legacy option, and introduce
 >     the new _OCI_CMD option with different semantics (see below) and an
 >     appropriate prompt;

 >   - we interpret both _OCI_ENTRYPOINT and _OCI_CMD as shell strings,
 >     which we subject to the usual shell quoting [1] and token
 >     recognition [2];

 > Since _OCI_ENTRYPOINT_ARGS used to be interpreted as a single string, we
 > can't easily change its meaning to be a space-separated list, as that
 > would break existing setups, which is the reason we make it legacy and
 > introduce a new option.

 > Ideally, we would like to default the new option _OCI_CMD to be the
 > quoted value of the previous _OCI_ENTRYPOINT_ARGS, but this is not
 > possible in Kconfig. Still, users that had a _OCI_ENTRYPOINT_ARGS set
 > will now get an early build error, and can still detect they need to do
 > something about it.

 > As for _OCI_ENTRYPOINT, it does not make much sense to support both
 > cases. Indeed, withoput splitting on spaces, we'd end up with an
 > entrypoint that would hava single item:

 >     {
 >         "config": {
 >             "entrypoint: [ "some string with some spaces" ]
 >         }
 >     }

 > which in this case would try to execute the program which name is
 > actually "some string with some spaces", so we do not expect that
 > existing entrypoints are set with any space in them, and so the new
 > behaviour, unlike for _OCI_ENTRYPOINT_ARGS vs. _OCI_CMD, is compatible
 > with existing configurations, and so we do not need to make it a legacy
 > option and introduce a new one.

 > [0] https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact
 > [1] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02
 > [2] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03

 > Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
 > Cc: Sergio Prado <sergio.prado@e-labworks.com>
 > Cc: Matthew Weber <matthew.weber@collins.com>

 > ---
 > Changes v1 -> v2:
 >   - drop _OCI_ENTRYPOINT_ARGS and replace with _OCI_CMD
 >   - accept values that have shell escapes and quotes, and spaces

Committed to 2022.02.x, thanks.

-- 
Bye, Peter Korsgaard
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-05-29  8:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-13 13:17 [Buildroot] [PATCH v2] fs/oci: entrypoint and command are space-separated lists yann.morin
2022-05-15 20:22 ` Peter Korsgaard
2022-05-29  8:34 ` Peter Korsgaard

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.