code: def construct_containerfile(
      bento: Bento,
      enable_buildkit: bool = True,
      *,
      features: t.Sequence[str] | None = None,
      add_header: bool = False,
  ) -> t.Generator[tuple[str, str], None, None]:
      from ..bento.bento import BentoInfo
      from ..bento.build_config import DockerOptions
      from ..models import ModelStore
      from ..models import copy_model
  
      dockerfile_path = "env/docker/Dockerfile"
      instruction: list[str] = []
  
      with fs.open_fs("temp://") as temp_fs, open(
          bento.path_of("bento.yaml"), "rb"
      ) as bento_yaml:
          tempdir = temp_fs.getsyspath("/")
          options = BentoInfo.from_yaml_file(bento_yaml)
          # tmpdir is our new build context.
          fs.mirror.mirror(bento._fs, temp_fs, copy_if_newer=True)
  
          # copy models from model store
          model_store = BentoMLContainer.model_store.get()
          bento_model_store = ModelStore(
              temp_fs.makedir("models", recreate=True)
          )
          for model in options.models:
              copy_model(
                  model.tag,
                  src_model_store=model_store,
                  target_model_store=bento_model_store,
              )
  
          # NOTE: dockerfile_template is already included in the
          # Dockerfile inside bento, and it is not relevant to
          # construct_containerfile. Hence it is safe to set it to None here.
          # See https://github.com/bentoml/BentoML/issues/3399.
          docker_attrs = bentoml_cattr.unstructure(options.docker)
          if (
              "dockerfile_template" in docker_attrs
              and docker_attrs["dockerfile_template"] is not None
          ):
              # NOTE: if users specify a dockerfile_template, we will
              # save it to /env/docker/Dockerfile.template. This is necessary
              # for the reconstruction of the Dockerfile.
              docker_attrs[
                  "dockerfile_template"
              ] = "env/docker/Dockerfile.template"
  
          dockerfile = generate_containerfile(
              docker=DockerOptions(**docker_attrs),
              build_ctx=tempdir,
              conda=options.conda,
              bento_fs=temp_fs,
              enable_buildkit=enable_buildkit,
              add_header=add_header,
          )
          instruction.append(dockerfile)
          if features is not None:
              diff = set(features).difference(FEATURES)
              if len(diff) > 0:
                  raise InvalidArgument(
                      f"Available features are: {FEATURES}. Invalid fields from provided: {diff}"
                  )
              PIP_CACHE_MOUNT = (
                  "--mount=type=cache,target=/root/.cache/pip "
                  if enable_buildkit
                  else ""
              )
              instruction.append(
                  "RUN %spip install bentoml[%s]"
                  % (PIP_CACHE_MOUNT, ",".join(features))
              )
          temp_fs.writetext(dockerfile_path, "\n".join(instruction))
          yield tempdir, temp_fs.getsyspath(dockerfile_path)
  
imports: from __future__ import annotations
  import contextlib
  import importlib
  import logging
  import os
  import sys
  import types
  import typing
  from typing import TYPE_CHECKING
  import fs
  import fs.mirror
  from simple_di import Provide
  from simple_di import inject
  from ...exceptions import InvalidArgument
  from ..configuration.containers import BentoMLContainer
  from ..utils import bentoml_cattr
  from .base import OCIBuilder
  from .generate import generate_containerfile
label_desc: Use image node_id 4 for calling a global function with example usage: construct_containerfile(bento, enable_buildkit) without return types