docs: def override_cluster_spec(self, srd):
          """
          Returns SystemRequirementsDict can be passed in a "systemRequirements"
          input to app-xxx/run, e.g. {'fn': {'clusterSpec': {initialInstanceCount: 3, version: "2.4.0", ..}}}
          Since full clusterSpec must be passed to the API server, we need to retrieve the cluster
          spec defined in app doc's systemRequirements and overwrite the field initialInstanceCount
          with the value the user passed to dx run for each entrypoint.
          initialInstanceCount is currently the only clusterSpec's field the user is allowed to change
          at runtime.
          A few scenarios when requesting instance count for different entrypoints with dx run 
          and the resulting merged systemRequirements (merged_cluster_spec). The bootstapScript
          field here is only one of many (version, ports, etc) that should be copied from app
          spec to merged_cluster_spec:
  
          Requested: {"*": 5}
          App doc: {"main": "clusterSpec": {"initialInstanceCount": 7, bootstrapScript: "x.sh"},
                  "other": "clusterSpec": {"initialInstanceCount": 9, bootstrapScript: "y.sh"}}
          Merged: {"main": "clusterSpec": {"initialInstanceCount": 5, bootstrapScript: "x.sh"},
                  "other": "clusterSpec": {"initialInstanceCount": 5, bootstrapScript: "y.sh"}}
          
          Requested: {"*": 15}
          App doc: {"main": "clusterSpec": {"initialInstanceCount": 7, bootstrapScript: "x.sh"},
                    "other": "clusterSpec": {"initialInstanceCount": 9, bootstrapScript: "y.sh"},
                    "*": "clusterSpec": {"initialInstanceCount": 11, bootstrapScript: "y.sh"}}
          Merged: {"main": "clusterSpec": {"initialInstanceCount": 15, bootstrapScript: "x.sh"},
                   "other": "clusterSpec": {"initialInstanceCount": 15, bootstrapScript: "y.sh"},
                   "*": "clusterSpec": {"initialInstanceCount": 15, bootstrapScript: "y.sh"}}
  
          Requested: {"main": 12}
          App doc: {"main": "clusterSpec": {"initialInstanceCount": 7, bootstrapScript: "x.sh"},
                    "other": "clusterSpec": {"initialInstanceCount": 9, bootstrapScript: "y.sh"}}
          Merged: {"main": "clusterSpec": {"initialInstanceCount": 12, bootstrapScript: "x.sh"}}
  
          Requested: {"main": 33}
          App doc: {"*": "clusterSpec": {"initialInstanceCount": 2, bootstrapScript: "z.sh"}}
          Merged: {"main": "clusterSpec": {"initialInstanceCount": 33, bootstrapScript: "z.sh"}}
  
          Requested: {"main": 22, "*": 11}
          App doc: {"*": "clusterSpec": {"initialInstanceCount": 2, bootstrapScript: "t.sh"}}
          Merged: {"main": "clusterSpec": {"initialInstanceCount": 22, bootstrapScript: "t.sh"},
                   "*": "clusterSpec": {"initialInstanceCount": 11, bootstrapScript: "t.sh"}}
          """
  
          merged_cluster_spec = copy.deepcopy(self.entrypoints)
  
          # Remove entrypoints without "clusterSpec"
          merged_cluster_spec = dict([(k, v) for k, v in merged_cluster_spec.items() if v.get("clusterSpec") is not None])
  
          # Remove entrypoints not provided in requested instance counts
          merged_cluster_spec = dict([(k, v) for k, v in merged_cluster_spec.items() if \
              k in srd.entrypoints or "*" in srd.entrypoints])
  
          # Overwrite values of self.entrypoints.clusterSpec with the ones from srd
          # Named entrypoint takes precedence over the wildcard
          for entry_pt, req in merged_cluster_spec.items():
              merged_cluster_spec[entry_pt]["clusterSpec"].update(
                  srd.entrypoints.get(entry_pt, srd.entrypoints.get("*"))["clusterSpec"])
  
          # Check if all entrypoints in srd are included in merged_cluster_spec
          # (if a named entrypoint was used in srd and such an entrypoint doesn't exist
          #  in app sys req, we need to take the cluster spec from the app's "*", if it exists)
          for entry_pt, req in srd.entrypoints.items():
              if entry_pt not in merged_cluster_spec and "*" in self.entrypoints and "clusterSpec" in self.entrypoints["*"]:
                  merged_cluster_spec[entry_pt] = {"clusterSpec": copy.deepcopy(self.entrypoints["*"]["clusterSpec"])}
                  merged_cluster_spec[entry_pt]["clusterSpec"].update(req["clusterSpec"])
  
          return SystemRequirementsDict(merged_cluster_spec)