code: def add_containerize_command(cli: Group) -> None:
      import click
      from click_option_group import optgroup
  
      from bentoml import container
      from bentoml._internal.configuration import get_debug_mode
      from bentoml._internal.container import FEATURES
      from bentoml._internal.container import REGISTERED_BACKENDS
      from bentoml._internal.container import determine_container_tag
      from bentoml._internal.container import enable_buildkit
      from bentoml.exceptions import BentoMLException
      from bentoml_cli.utils import kwargs_transformers
      from bentoml_cli.utils import normalize_none_type
      from bentoml_cli.utils import opt_callback
      from bentoml_cli.utils import validate_container_tag
  
      @cli.command()
      @click.argument(
          "bento_tag", type=click.STRING, metavar="BENTO:TAG"
      )
      @click.option(
          "-t",
          "--image-tag",
          "--docker-image-tag",
          metavar="NAME:TAG",
          help="Name and optionally a tag (format: ``name:tag``) for building container, defaults to the bento tag.",
          required=False,
          callback=validate_container_tag,
          multiple=True,
      )
      @click.option(
          "--backend",
          help="Define builder backend. Available: {}".format(
              ", ".join(map(lambda s: f"``{s}``", REGISTERED_BACKENDS))
          ),
          required=False,
          default="docker",
          envvar="BENTOML_CONTAINERIZE_BACKEND",
          type=click.STRING,
      )
      @click.option(
          "--enable-features",
          multiple=True,
          nargs=1,
          metavar="FEATURE[,FEATURE]",
          help="Enable additional BentoML features. Available features are: {}.".format(
              ", ".join(map(lambda s: f"``{s}``", FEATURES))
          ),
      )
      @click.option(
          "--opt",
          help="Define options for given backend. (format: ``--opt target=foo --opt build-arg=foo=BAR --opt iidfile:/path/to/file --opt no-cache``)",
          required=False,
          multiple=True,
          callback=opt_callback,
          metavar="ARG=VALUE[,ARG=VALUE]",
      )
      @click.option(
          "--run-as-root",
          help="Whether to run backend with as root.",
          is_flag=True,
          required=False,
          default=False,
          type=bool,
      )
      @optgroup.group(
          "Equivalent options",
          help="Equivalent option group for backward compatibility",
      )
      @compatible_options_group
      @optgroup.group(
          "Buildx options",
          help="[Only available with '--backend=buildx']",
      )
      @buildx_options_group
      @kwargs_transformers(transformer=normalize_none_type)
      def containerize(  # type: ignore
          bento_tag: str,
          image_tag: tuple[str] | None,
          backend: DefaultBuilder,
          enable_features: tuple[str] | None,
          run_as_root: bool,
          _memoized: dict[str, t.Any],
          **kwargs: t.Any,  # pylint: disable=unused-argument
      ) -> None:
          """Containerizes given Bento into an OCI-compliant container, with any given OCI builder.
  
          \b
  
          ``BENTO`` is the target BentoService to be containerized, referenced by its name
          and version in format of name:version. For example: ``iris_classifier:v1.2.0``
  
          \b
          ``bentoml containerize`` command also supports the use of the ``latest`` tag
          which will automatically use the last built version of your Bento.
  
          \b
          You can provide a tag for the image built by Bento using the
          ``--image-tag`` flag.
  
          \b
          You can also prefixing the tag with a hostname for the repository you wish to push to.
  
          .. code-block:: bash
  
             $ bentoml containerize iris_classifier:latest -t repo-address.com:username/iris
  
          This would build an image called ``username/iris:latest`` and push it to docker repository at ``repo-address.com``.
  
          \b
          By default, the ``containerize`` command will use the current credentials provided by each backend implementation.
  
          \b
          ``bentoml containerize`` also leverage BuildKit features such as multi-node
          builds for cross-platform images, more efficient caching, and more secure builds.
          BuildKit will be enabled by default by each backend implementation. To opt-out of BuildKit, set ``DOCKER_BUILDKIT=0``:
  
          .. code-block:: bash
  
              $ DOCKER_BUILDKIT=0 bentoml containerize iris_classifier:latest
  
          \b
          ``bentoml containerize`` is backend-agnostic, meaning that it can use any OCI-compliant builder to build the container image.
          By default, it will use the ``docker`` backend, which will use the local Docker daemon to build the image.
          You can use the ``--backend`` flag to specify a different backend. Note that backend flags will now be unified via ``--opt``.
  
          ``--opt`` accepts multiple flags, and it works with all backend options.
  
          \b
          To pass a boolean flag (e.g: ``--no-cache``), use ``--opt no-cache``.
  
          \b
          To pass a key-value pair (e.g: ``--build-arg FOO=BAR``), use ``--opt build-arg=FOO=BAR`` or ``--opt build-arg:FOO=BAR``. Make sure to quote the value if it contains spaces.
  
          \b
          To pass a argument with one value (path, integer, etc) (e.g: ``--cgroup-parent cgroupv2``), use ``--opt cgroup-parent=cgroupv2`` or ``--opt cgroup-parent:cgroupv2``.
          """
  
          # we can filter out all options that are None or False.
          _memoized = {k: v for k, v in _memoized.items() if v}
          logger.debug("Memoized: %s", _memoized)
  
          # Run healthcheck before containerizing
          # build will also run healthcheck, but we want to fail early.
          try:
              container.health(backend)
          except subprocess.CalledProcessError:
              raise BentoMLException(
                  f"Backend {backend} is not healthy"
              )
  
          # --progress is not available without BuildKit.
          if (
              not enable_buildkit(backend=backend)
              and "progress" in _memoized
          ):
              _memoized.pop("progress")
          elif get_debug_mode():
              _memoized["progress"] = "plain"
          _memoized["_run_as_root"] = run_as_root
  
          features: tuple[str] | None = None
          if enable_features:
              features = tuple(
                  itertools.chain.from_iterable(
                      map(lambda s: s.split(","), enable_features)
                  )
              )
          result = container.build(
              bento_tag,
              backend=backend,
              image_tag=image_tag,
              features=features,
              **_memoized,
          )
  
          if result is not None:
              tags = determine_container_tag(
                  bento_tag, image_tag=image_tag
              )
  
              container_runtime = backend
              # This logic determines some of the output messages.
              if backend == "buildah":
                  if shutil.which("podman") is None:
                      logger.warning(
                          "'buildah' are only used to build the image. To run the image, 'podman' is required to be installed (podman not found under PATH). See https://podman.io/getting-started/installation."
                      )
                      sys.exit(0)
                  else:
                      container_runtime = "podman"
              elif backend == "buildx":
                  # buildx is a syntatic sugar for docker buildx build
                  container_runtime = "docker"
              elif backend == "buildctl":
                  if shutil.which("docker") is not None:
                      container_runtime = "docker"
                  elif shutil.which("podman") is not None:
                      container_runtime = "podman"
                  elif shutil.which("nerdctl") is not None:
                      container_runtime = "nerdctl"
                  else:
                      click.echo(
                          click.style(
                              "To load image built with 'buildctl' requires one of "
                              "docker, podman, nerdctl (None are found in PATH). "
                              "Make sure they are visible to PATH and try again.",
                              fg="yellow",
                          ),
                          color=True,
                      )
                      sys.exit(0)
                  if "output" not in _memoized:
                      tmp_path = tempfile.gettempdir()
                      type_prefix = "type=oci,name="
                      if container_runtime == "docker":
                          type_prefix = "type=docker,name=docker.io/"
                      click.echo(
                          click.style(
                              "Autoconfig is now deprecated and will be removed "
                              "in the next future release. We recommend setting "
                              "output to a tarfile should you wish to load the "
                              "image locally. For example:",
                              fg="yellow",
                          ),
                          color=True,
                      )
                      click.echo(
                          click.style(
                              f"    bentoml containerize {bento_tag} --backend buildctl --opt output={type_prefix}{tags[0]},dest={tmp_path}/{tags[0].replace(':', '_')}.tar\n"
                              f"    {container_runtime} load -i {tmp_path}/{tags[0].replace(':', '_')}.tar",
                              fg="yellow",
                          ),
                          color=True,
                      )
                      o = subprocess.check_output(
                          [container_runtime, "load"], input=result
                      )
                      if get_debug_mode():
                          click.echo(o.decode("utf-8").strip())
                      sys.exit(0)
                  return result
  
              click.echo(
                  f'Successfully built Bento container for "{bento_tag}" with tag(s) "{",".join(tags)}"',
              )
              instructions = (
                  "To run your newly built Bento container, run:\n"
                  + f"    {container_runtime} run --rm -p 3000:3000 {tags[0]}\n"
              )
  
              if features is not None and any(
                  has_grpc in features
                  for has_grpc in (
                      "all",
                      "grpc",
                      "grpc-reflection",
                      "grpc-channelz",
                  )
              ):
                  instructions += (
                      "To serve with gRPC instead, run:\n"
                      + f"    {container_runtime} run --rm -p 3000:3000 -p 3001:3001 {tags[0]} serve-grpc\n"
                  )
              click.echo(instructions, nl=False)
              raise SystemExit(0)
          raise SystemExit(1)
  
file_path: BentoML/src/bentoml_cli/containerize.py
imports: from __future__ import annotations
  import itertools
  import logging
  import shutil
  import subprocess
  import sys
  import tempfile
  import typing
  from functools import partial
label_desc: Use image node_id 4 for calling a global function with example usage: add_containerize_command(cli) and returns: result