buildroot/fs/oci/oci.mk

87 lines
2.5 KiB
Makefile
Raw Normal View History

################################################################################
#
# Build the oci image
#
################################################################################
ROOTFS_OCI_DEPENDENCIES = host-sloci-image
# architecture - take it from Go
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))
fs/oci: entrypoint and command are space-separated lists The prompt and variable name for the OCI "entrypoint arguments" are somewhat incorrect. Indeed, they are in fact used 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 fields 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 two 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, without splitting on spaces, we'd end up with an entrypoint that would have a 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> Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
2022-05-13 07:17:45 -06:00
# 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))
ifneq ($(OCI_AUTHOR),)
OCI_SLOCI_IMAGE_OPTS += --author "$(OCI_AUTHOR)"
endif
# username or UID
OCI_UID = $(call qstrip,$(BR2_TARGET_ROOTFS_OCI_UID))
ifneq ($(OCI_UID),)
OCI_SLOCI_IMAGE_OPTS += --user "$(OCI_UID)"
endif
# labels
OCI_LABELS = $(call qstrip,$(BR2_TARGET_ROOTFS_OCI_LABELS))
ifneq ($(OCI_LABELS),)
OCI_SLOCI_IMAGE_OPTS += \
$(foreach label,$(OCI_LABELS),--label "$(label)")
endif
# environment variables
OCI_ENV_VARS = $(call qstrip,$(BR2_TARGET_ROOTFS_OCI_ENV_VARS))
ifneq ($(OCI_ENV_VARS),)
OCI_SLOCI_IMAGE_OPTS += \
$(foreach var,$(OCI_ENV_VARS),--env "$(var)")
endif
# working directory
OCI_WORKDIR = $(call qstrip,$(BR2_TARGET_ROOTFS_OCI_WORKDIR))
ifneq ($(OCI_WORKDIR),)
OCI_SLOCI_IMAGE_OPTS += --working-dir "$(OCI_WORKDIR)"
endif
# ports
OCI_PORTS = $(call qstrip,$(BR2_TARGET_ROOTFS_OCI_PORTS))
ifneq ($(OCI_PORTS),)
OCI_SLOCI_IMAGE_OPTS += \
$(foreach port,$(OCI_PORTS),--port "$(port)")
endif
# tag
OCI_TAG = $(or $(call qstrip,$(BR2_TARGET_ROOTFS_OCI_TAG)),latest)
# enable tar archive
ifeq ($(BR2_TARGET_ROOTFS_OCI_ARCHIVE),y)
OCI_SLOCI_IMAGE_OPTS += --tar
endif
define ROOTFS_OCI_CMD
rm -rf $(BINARIES_DIR)/rootfs-oci
$(HOST_DIR)/bin/sloci-image $(OCI_SLOCI_IMAGE_OPTS) $(TARGET_DIR) \
$(BINARIES_DIR)/rootfs-oci:$(OCI_TAG)
endef
$(eval $(rootfs))