Revision 938adc87

b/lib/bdev.py
2802 2802
      raise ValueError("Invalid configuration data %s" % str(unique_id))
2803 2803

  
2804 2804
    self.driver, self.vol_name = unique_id
2805
    self.ext_params = params
2805 2806

  
2806 2807
    self.major = self.minor = None
2807 2808
    self.Attach()
......
2820 2821

  
2821 2822
    # Call the External Storage's create script,
2822 2823
    # to provision a new Volume inside the External Storage
2823
    _ExtStorageAction(constants.ES_ACTION_CREATE, unique_id, str(size))
2824
    _ExtStorageAction(constants.ES_ACTION_CREATE, unique_id,
2825
                      params, str(size))
2824 2826

  
2825 2827
    return ExtStorageDevice(unique_id, children, size, params)
2826 2828

  
......
2837 2839

  
2838 2840
    # Call the External Storage's remove script,
2839 2841
    # to remove the Volume from the External Storage
2840
    _ExtStorageAction(constants.ES_ACTION_REMOVE, self.unique_id)
2842
    _ExtStorageAction(constants.ES_ACTION_REMOVE, self.unique_id,
2843
                      self.ext_params)
2841 2844

  
2842 2845
  def Rename(self, new_id):
2843 2846
    """Rename this device.
......
2857 2860
    # Call the External Storage's attach script,
2858 2861
    # to attach an existing Volume to a block device under /dev
2859 2862
    self.dev_path = _ExtStorageAction(constants.ES_ACTION_ATTACH,
2860
                                      self.unique_id)
2863
                                      self.unique_id, self.ext_params)
2861 2864

  
2862 2865
    try:
2863 2866
      st = os.stat(self.dev_path)
......
2891 2894

  
2892 2895
    # Call the External Storage's detach script,
2893 2896
    # to detach an existing Volume from it's block device under /dev
2894
    _ExtStorageAction(constants.ES_ACTION_DETACH, self.unique_id)
2897
    _ExtStorageAction(constants.ES_ACTION_DETACH, self.unique_id,
2898
                      self.ext_params)
2895 2899

  
2896 2900
    self.minor = None
2897 2901
    self.dev_path = None
......
2932 2936
    # Call the External Storage's grow script,
2933 2937
    # to grow an existing Volume inside the External Storage
2934 2938
    _ExtStorageAction(constants.ES_ACTION_GROW, self.unique_id,
2935
                      str(self.size), grow=str(new_size))
2939
                      self.ext_params, str(self.size), grow=str(new_size))
2936 2940

  
2937 2941
  def SetInfo(self, text):
2938 2942
    """Update metadata with info text.
......
2948 2952
    # Call the External Storage's setinfo script,
2949 2953
    # to set metadata for an existing Volume inside the External Storage
2950 2954
    _ExtStorageAction(constants.ES_ACTION_SETINFO, self.unique_id,
2951
                      metadata=text)
2955
                      self.ext_params, metadata=text)
2952 2956

  
2953 2957

  
2954
def _ExtStorageAction(action, unique_id, size=None, grow=None, metadata=None):
2958
def _ExtStorageAction(action, unique_id, ext_params,
2959
                      size=None, grow=None, metadata=None):
2955 2960
  """Take an External Storage action.
2956 2961

  
2957 2962
  Take an External Storage action concerning or affecting
......
2963 2968
  @type unique_id: tuple (driver, vol_name)
2964 2969
  @param unique_id: a tuple containing the type of ExtStorage (driver)
2965 2970
                    and the Volume name
2971
  @type ext_params: dict
2972
  @param ext_params: ExtStorage parameters
2966 2973
  @type size: integer
2967 2974
  @param size: the size of the Volume in mebibytes
2968 2975
  @type grow: integer
......
2980 2987
    _ThrowError("%s" % inst_es)
2981 2988

  
2982 2989
  # Create the basic environment for the driver's scripts
2983
  create_env = _ExtStorageEnvironment(unique_id, size, grow, metadata)
2990
  create_env = _ExtStorageEnvironment(unique_id, ext_params, size,
2991
                                      grow, metadata)
2984 2992

  
2985 2993
  # Do not use log file for action `attach' as we need
2986 2994
  # to get the output from RunResult
......
3053 3061
  # an optional one
3054 3062
  es_files = dict.fromkeys(constants.ES_SCRIPTS, True)
3055 3063

  
3056
  for filename in es_files:
3064
  es_files[constants.ES_PARAMETERS_FILE] = True
3065

  
3066
  for (filename, _) in es_files.items():
3057 3067
    es_files[filename] = utils.PathJoin(es_dir, filename)
3058 3068

  
3059 3069
    try:
......
3071 3081
        return False, ("File '%s' under path '%s' is not executable" %
3072 3082
                       (filename, es_dir))
3073 3083

  
3084
  parameters = []
3085
  if constants.ES_PARAMETERS_FILE in es_files:
3086
    parameters_file = es_files[constants.ES_PARAMETERS_FILE]
3087
    try:
3088
      parameters = utils.ReadFile(parameters_file).splitlines()
3089
    except EnvironmentError, err:
3090
      return False, ("Error while reading the EXT parameters file at %s: %s" %
3091
                     (parameters_file, utils.ErrnoOrStr(err)))
3092
    parameters = [v.split(None, 1) for v in parameters]
3093

  
3074 3094
  es_obj = \
3075 3095
    objects.ExtStorage(name=name, path=es_dir,
3076 3096
                       create_script=es_files[constants.ES_SCRIPT_CREATE],
......
3078 3098
                       grow_script=es_files[constants.ES_SCRIPT_GROW],
3079 3099
                       attach_script=es_files[constants.ES_SCRIPT_ATTACH],
3080 3100
                       detach_script=es_files[constants.ES_SCRIPT_DETACH],
3081
                       setinfo_script=es_files[constants.ES_SCRIPT_SETINFO])
3101
                       setinfo_script=es_files[constants.ES_SCRIPT_SETINFO],
3102
                       verify_script=es_files[constants.ES_SCRIPT_VERIFY],
3103
                       supported_parameters=parameters)
3082 3104
  return True, es_obj
3083 3105

  
3084 3106

  
3085
def _ExtStorageEnvironment(unique_id, size=None, grow=None, metadata=None):
3107
def _ExtStorageEnvironment(unique_id, ext_params,
3108
                           size=None, grow=None, metadata=None):
3086 3109
  """Calculate the environment for an External Storage script.
3087 3110

  
3088 3111
  @type unique_id: tuple (driver, vol_name)
3089 3112
  @param unique_id: ExtStorage pool and name of the Volume
3113
  @type ext_params: dict
3114
  @param ext_params: the EXT parameters
3090 3115
  @type size: string
3091 3116
  @param size: size of the Volume (in mebibytes)
3092 3117
  @type grow: string
......
3102 3127
  result = {}
3103 3128
  result["VOL_NAME"] = vol_name
3104 3129

  
3130
  # EXT params
3131
  for pname, pvalue in ext_params.items():
3132
    result["EXTP_%s" % pname.upper()] = str(pvalue)
3133

  
3105 3134
  if size is not None:
3106 3135
    result["VOL_SIZE"] = size
3107 3136

  
b/lib/cmdlib.py
7302 7302
    # TODO: Implement support changing VG while recreating
7303 7303
    constants.IDISK_VG,
7304 7304
    constants.IDISK_METAVG,
7305
    constants.IDISK_PROVIDER,
7305 7306
    ]))
7306 7307

  
7307 7308
  def _RunAllocator(self):
......
9192 9193
    elif template_name == constants.DT_RBD:
9193 9194
      logical_id_fn = lambda idx, _, disk: ("rbd", names[idx])
9194 9195
    elif template_name == constants.DT_EXT:
9195
      logical_id_fn = lambda idx, _, disk: ("ext", names[idx])
9196
      def logical_id_fn(idx, _, disk):
9197
        provider = disk.get(constants.IDISK_PROVIDER, None)
9198
        if provider is None:
9199
          raise errors.ProgrammerError("Disk template is %s, but '%s' is"
9200
                                       " not found", constants.DT_EXT,
9201
                                       constants.IDISK_PROVIDER)
9202
        return (provider, names[idx])
9196 9203
    else:
9197 9204
      raise errors.ProgrammerError("Unknown disk template '%s'" % template_name)
9198 9205

  
9199 9206
    dev_type = _DISK_TEMPLATE_DEVICE_TYPE[template_name]
9200 9207

  
9201 9208
    for idx, disk in enumerate(disk_info):
9209
      params = {}
9210
      # Only for the Ext template add disk_info to params
9211
      if template_name == constants.DT_EXT:
9212
        params[constants.IDISK_PROVIDER] = disk[constants.IDISK_PROVIDER]
9213
        for key in disk:
9214
          if key not in constants.IDISK_PARAMS:
9215
            params[key] = disk[key]
9202 9216
      disk_index = idx + base_index
9203 9217
      size = disk[constants.IDISK_SIZE]
9204 9218
      feedback_fn("* disk %s, size %s" %
......
9207 9221
                                logical_id=logical_id_fn(idx, disk_index, disk),
9208 9222
                                iv_name="disk/%d" % disk_index,
9209 9223
                                mode=disk[constants.IDISK_MODE],
9210
                                params={}))
9224
                                params=params))
9211 9225

  
9212 9226
  return disks
9213 9227

  
......
9657 9671
  @param op: The instance opcode
9658 9672
  @param default_vg: The default_vg to assume
9659 9673

  
9660
  @return: The computer disks
9674
  @return: The computed disks
9661 9675

  
9662 9676
  """
9663 9677
  disks = []
......
9675 9689
      raise errors.OpPrereqError("Invalid disk size '%s'" % size,
9676 9690
                                 errors.ECODE_INVAL)
9677 9691

  
9692
    ext_provider = disk.get(constants.IDISK_PROVIDER, None)
9693
    if ext_provider and op.disk_template != constants.DT_EXT:
9694
      raise errors.OpPrereqError("The '%s' option is only valid for the %s"
9695
                                 " disk template, not %s" %
9696
                                 (constants.IDISK_PROVIDER, constants.DT_EXT,
9697
                                 op.disk_template), errors.ECODE_INVAL)
9698

  
9678 9699
    data_vg = disk.get(constants.IDISK_VG, default_vg)
9679 9700
    new_disk = {
9680 9701
      constants.IDISK_SIZE: size,
9681 9702
      constants.IDISK_MODE: mode,
9682 9703
      constants.IDISK_VG: data_vg,
9683 9704
      }
9705

  
9684 9706
    if constants.IDISK_METAVG in disk:
9685 9707
      new_disk[constants.IDISK_METAVG] = disk[constants.IDISK_METAVG]
9686 9708
    if constants.IDISK_ADOPT in disk:
9687 9709
      new_disk[constants.IDISK_ADOPT] = disk[constants.IDISK_ADOPT]
9710

  
9711
    # For extstorage, demand the `provider' option and add any
9712
    # additional parameters (ext-params) to the dict
9713
    if op.disk_template == constants.DT_EXT:
9714
      if ext_provider:
9715
        new_disk[constants.IDISK_PROVIDER] = ext_provider
9716
        for key in disk:
9717
          if key not in constants.IDISK_PARAMS:
9718
            new_disk[key] = disk[key]
9719
      else:
9720
        raise errors.OpPrereqError("Missing provider for template '%s'" %
9721
                                   constants.DT_EXT, errors.ECODE_INVAL)
9722

  
9688 9723
    disks.append(new_disk)
9689 9724

  
9690 9725
  return disks
......
9751 9786
    # check disks. parameter names and consistent adopt/no-adopt strategy
9752 9787
    has_adopt = has_no_adopt = False
9753 9788
    for disk in self.op.disks:
9754
      utils.ForceDictType(disk, constants.IDISK_PARAMS_TYPES)
9789
      if self.op.disk_template != constants.DT_EXT:
9790
        utils.ForceDictType(disk, constants.IDISK_PARAMS_TYPES)
9755 9791
      if constants.IDISK_ADOPT in disk:
9756 9792
        has_adopt = True
9757 9793
      else:
......
10544 10580

  
10545 10581
    _CheckNicsBridgesExist(self, self.nics, self.pnode.name)
10546 10582

  
10583
    #TODO: _CheckExtParams (remotely)
10584
    # Check parameters for extstorage
10585

  
10547 10586
    # memory check on primary node
10548 10587
    #TODO(dynmem): use MINMEM for checking
10549 10588
    if self.op.start:
b/lib/constants.py
676 676
ES_ACTION_ATTACH = "attach"
677 677
ES_ACTION_DETACH = "detach"
678 678
ES_ACTION_SETINFO = "setinfo"
679
ES_ACTION_VERIFY = "verify"
679 680

  
680 681
ES_SCRIPT_CREATE = ES_ACTION_CREATE
681 682
ES_SCRIPT_REMOVE = ES_ACTION_REMOVE
......
683 684
ES_SCRIPT_ATTACH = ES_ACTION_ATTACH
684 685
ES_SCRIPT_DETACH = ES_ACTION_DETACH
685 686
ES_SCRIPT_SETINFO = ES_ACTION_SETINFO
687
ES_SCRIPT_VERIFY = ES_ACTION_VERIFY
686 688
ES_SCRIPTS = frozenset([
687 689
  ES_SCRIPT_CREATE,
688 690
  ES_SCRIPT_REMOVE,
689 691
  ES_SCRIPT_GROW,
690 692
  ES_SCRIPT_ATTACH,
691 693
  ES_SCRIPT_DETACH,
692
  ES_SCRIPT_SETINFO
694
  ES_SCRIPT_SETINFO,
695
  ES_SCRIPT_VERIFY
693 696
  ])
694 697

  
698
ES_PARAMETERS_FILE = "parameters.list"
699

  
695 700
# ssh constants
696 701
SSH = "ssh"
697 702
SCP = "scp"
......
1175 1180
IDISK_ADOPT = "adopt"
1176 1181
IDISK_VG = "vg"
1177 1182
IDISK_METAVG = "metavg"
1183
IDISK_PROVIDER = "provider"
1178 1184
IDISK_PARAMS_TYPES = {
1179 1185
  IDISK_SIZE: VTYPE_SIZE,
1180 1186
  IDISK_MODE: VTYPE_STRING,
1181 1187
  IDISK_ADOPT: VTYPE_STRING,
1182 1188
  IDISK_VG: VTYPE_STRING,
1183 1189
  IDISK_METAVG: VTYPE_STRING,
1190
  IDISK_PROVIDER: VTYPE_STRING,
1184 1191
  }
1185 1192
IDISK_PARAMS = frozenset(IDISK_PARAMS_TYPES.keys())
1186 1193

  
b/lib/objects.py
909 909
        constants.LDP_POOL: dt_params[constants.RBD_POOL],
910 910
        }))
911 911

  
912
    elif disk_template == constants.DT_EXT:
913
      result.append(constants.DISK_LD_DEFAULTS[constants.LD_EXT])
914

  
912 915
    return result
913 916

  
914 917

  
......
1249 1252
    "attach_script",
1250 1253
    "detach_script",
1251 1254
    "setinfo_script",
1255
    "verify_script",
1256
    "supported_parameters",
1252 1257
    ]
1253 1258

  
1254 1259

  

Also available in: Unified diff