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