Revision e15a00dc
b/NEWS | ||
---|---|---|
36 | 36 |
- Hail and hbal now have the (optional) capability of accessing average CPU |
37 | 37 |
load information through the monitoring deamon, and to use it to dynamically |
38 | 38 |
adapt the allocation of instances. |
39 |
- Hotplug support. Introduce new option '--hotplug' to ``gnt-instance modify`` |
|
40 |
so that disk and NIC modifications take effect without the need of actual |
|
41 |
reboot. There are a couple of constrains currently for this feature: |
|
42 |
|
|
43 |
- only KVM hypervisor (versions >= 1.0) supports it, |
|
44 |
- one can not (yet) hotplug a disk using userspace access mode for RBD |
|
45 |
- in case of a downgrade instances should suffer a reboot in order to |
|
46 |
be migratable (due to core change of runtime files) |
|
39 | 47 |
|
40 | 48 |
Misc changes |
41 | 49 |
~~~~~~~~~~~~ |
... | ... | |
102 | 110 |
New features |
103 | 111 |
~~~~~~~~~~~~ |
104 | 112 |
|
105 |
- Hotplug support. Introduce new option --hotplug to gnt-instance modify |
|
106 |
so that disk and NIC modifications take effect without the need of actual |
|
107 |
reboot. This feature is currently supported only for KVM hypervisor with |
|
108 |
version greater than 1.0. |
|
109 | 113 |
- DRBD 8.4 support. Depending on the installed DRBD version, Ganeti now uses |
110 | 114 |
the correct command syntax. It is possible to use different DRBD versions |
111 | 115 |
on different nodes as long as they are compatible to each other. This |
b/lib/cli.py | ||
---|---|---|
1644 | 1644 |
|
1645 | 1645 |
HOTPLUG_OPT = cli_option("--hotplug", dest="hotplug", |
1646 | 1646 |
action="store_true", default=False, |
1647 |
help="Try to hotplug device")
|
|
1647 |
help="Hotplug supported devices (NICs and Disks)")
|
|
1648 | 1648 |
|
1649 | 1649 |
#: Options provided by all commands |
1650 | 1650 |
COMMON_OPTS = [DEBUG_OPT, REASON_OPT] |
b/lib/client/gnt_instance.py | ||
---|---|---|
1315 | 1315 |
|
1316 | 1316 |
nics = _ConvertNicDiskModifications(opts.nics) |
1317 | 1317 |
for action, _, __ in nics: |
1318 |
if action == constants.DDM_MODIFY and opts.hotplug: |
|
1318 |
if action == constants.DDM_MODIFY and opts.hotplug and not opts.force:
|
|
1319 | 1319 |
usertext = ("You are about to hot-modify a NIC. This will be done" |
1320 | 1320 |
" by removing the exisiting and then adding a new one." |
1321 | 1321 |
" Network connection might be lost. Continue?") |
... | ... | |
1364 | 1364 |
ToStdout("Modified instance %s", args[0]) |
1365 | 1365 |
for param, data in result: |
1366 | 1366 |
ToStdout(" - %-5s -> %s", param, data) |
1367 |
if not opts.hotplug: |
|
1368 |
ToStdout("Please don't forget that most parameters take effect" |
|
1369 |
" only at the next (re)start of the instance initiated by" |
|
1370 |
" ganeti; restarting from within the instance will" |
|
1371 |
" not be enough.") |
|
1367 |
ToStdout("Please don't forget that most parameters take effect" |
|
1368 |
" only at the next (re)start of the instance initiated by" |
|
1369 |
" ganeti; restarting from within the instance will" |
|
1370 |
" not be enough.") |
|
1372 | 1371 |
return 0 |
1373 | 1372 |
|
1374 | 1373 |
|
b/lib/cmdlib/instance.py | ||
---|---|---|
2228 | 2228 |
if op == constants.DDM_REMOVE: |
2229 | 2229 |
assert not params |
2230 | 2230 |
|
2231 |
if remove_fn is not None: |
|
2232 |
remove_fn(absidx, item, private) |
|
2233 |
|
|
2234 | 2231 |
changes = [("%s/%s" % (kind, absidx), "remove")] |
2235 | 2232 |
|
2233 |
if remove_fn is not None: |
|
2234 |
msg = remove_fn(absidx, item, private) |
|
2235 |
if msg: |
|
2236 |
changes.append(("%s/%s" % (kind, absidx), msg)) |
|
2237 |
|
|
2236 | 2238 |
assert container[absidx] == item |
2237 | 2239 |
del container[absidx] |
2238 | 2240 |
elif op == constants.DDM_MODIFY: |
... | ... | |
3236 | 3238 |
|
3237 | 3239 |
def _HotplugDevice(self, action, dev_type, device, extra, seq): |
3238 | 3240 |
self.LogInfo("Trying to hotplug device...") |
3241 |
msg = "hotplug:" |
|
3239 | 3242 |
result = self.rpc.call_hotplug_device(self.instance.primary_node, |
3240 | 3243 |
self.instance, action, dev_type, |
3241 | 3244 |
(device, self.instance), |
... | ... | |
3243 | 3246 |
if result.fail_msg: |
3244 | 3247 |
self.LogWarning("Could not hotplug device: %s" % result.fail_msg) |
3245 | 3248 |
self.LogInfo("Continuing execution..") |
3249 |
msg += "failed" |
|
3246 | 3250 |
else: |
3247 | 3251 |
self.LogInfo("Hotplug done.") |
3252 |
msg += "done" |
|
3253 |
return msg |
|
3248 | 3254 |
|
3249 | 3255 |
def _CreateNewDisk(self, idx, params, _): |
3250 | 3256 |
"""Creates a new disk. |
... | ... | |
3271 | 3277 |
disks=[(idx, disk, 0)], |
3272 | 3278 |
cleanup=new_disks) |
3273 | 3279 |
|
3280 |
changes = [ |
|
3281 |
("disk/%d" % idx, |
|
3282 |
"add:size=%s,mode=%s" % (disk.size, disk.mode)), |
|
3283 |
] |
|
3274 | 3284 |
if self.op.hotplug: |
3275 | 3285 |
result = self.rpc.call_blockdev_assemble(self.instance.primary_node, |
3276 | 3286 |
(disk, self.instance), |
3277 | 3287 |
self.instance.name, True, idx) |
3278 | 3288 |
if result.fail_msg: |
3289 |
changes.append(("disk/%d" % idx, "assemble:failed")) |
|
3279 | 3290 |
self.LogWarning("Can't assemble newly created disk %d: %s", |
3280 | 3291 |
idx, result.fail_msg) |
3281 | 3292 |
else: |
3282 | 3293 |
_, link_name = result.payload |
3283 |
self._HotplugDevice(constants.HOTPLUG_ACTION_ADD, |
|
3284 |
constants.HOTPLUG_TARGET_DISK, |
|
3285 |
disk, link_name, idx) |
|
3294 |
msg = self._HotplugDevice(constants.HOTPLUG_ACTION_ADD, |
|
3295 |
constants.HOTPLUG_TARGET_DISK, |
|
3296 |
disk, link_name, idx) |
|
3297 |
changes.append(("disk/%d" % idx, msg)) |
|
3286 | 3298 |
|
3287 |
return (disk, [ |
|
3288 |
("disk/%d" % idx, "add:size=%s,mode=%s" % (disk.size, disk.mode)), |
|
3289 |
]) |
|
3299 |
return (disk, changes) |
|
3290 | 3300 |
|
3291 | 3301 |
def _PostAddDisk(self, _, disk): |
3292 | 3302 |
if not WaitForSync(self, self.instance, disks=[disk], |
... | ... | |
3320 | 3330 |
"""Removes a disk. |
3321 | 3331 |
|
3322 | 3332 |
""" |
3333 |
hotmsg = "" |
|
3323 | 3334 |
if self.op.hotplug: |
3324 |
self._HotplugDevice(constants.HOTPLUG_ACTION_REMOVE, |
|
3325 |
constants.HOTPLUG_TARGET_DISK, |
|
3326 |
root, None, idx) |
|
3335 |
hotmsg = self._HotplugDevice(constants.HOTPLUG_ACTION_REMOVE,
|
|
3336 |
constants.HOTPLUG_TARGET_DISK,
|
|
3337 |
root, None, idx)
|
|
3327 | 3338 |
ShutdownInstanceDisks(self, self.instance, [root]) |
3328 | 3339 |
|
3329 | 3340 |
(anno_disk,) = AnnotateDiskParams(self.instance, [root], self.cfg) |
... | ... | |
3340 | 3351 |
if root.dev_type in constants.DTS_DRBD: |
3341 | 3352 |
self.cfg.AddTcpUdpPort(root.logical_id[2]) |
3342 | 3353 |
|
3354 |
return hotmsg |
|
3355 |
|
|
3343 | 3356 |
def _CreateNewNic(self, idx, params, private): |
3344 | 3357 |
"""Creates data structure for a new network interface. |
3345 | 3358 |
|
... | ... | |
3355 | 3368 |
nicparams=nicparams) |
3356 | 3369 |
nobj.uuid = self.cfg.GenerateUniqueID(self.proc.GetECId()) |
3357 | 3370 |
|
3358 |
if self.op.hotplug: |
|
3359 |
self._HotplugDevice(constants.HOTPLUG_ACTION_ADD, |
|
3360 |
constants.HOTPLUG_TARGET_NIC, |
|
3361 |
nobj, None, idx) |
|
3362 |
|
|
3363 |
desc = [ |
|
3371 |
changes = [ |
|
3364 | 3372 |
("nic.%d" % idx, |
3365 | 3373 |
"add:mac=%s,ip=%s,mode=%s,link=%s,network=%s" % |
3366 | 3374 |
(mac, ip, private.filled[constants.NIC_MODE], |
3367 | 3375 |
private.filled[constants.NIC_LINK], net)), |
3368 | 3376 |
] |
3369 | 3377 |
|
3370 |
return (nobj, desc) |
|
3378 |
if self.op.hotplug: |
|
3379 |
msg = self._HotplugDevice(constants.HOTPLUG_ACTION_ADD, |
|
3380 |
constants.HOTPLUG_TARGET_NIC, |
|
3381 |
nobj, None, idx) |
|
3382 |
changes.append(("nic.%d" % idx, msg)) |
|
3383 |
|
|
3384 |
return (nobj, changes) |
|
3371 | 3385 |
|
3372 | 3386 |
def _ApplyNicMods(self, idx, nic, params, private): |
3373 | 3387 |
"""Modifies a network interface. |
... | ... | |
3393 | 3407 |
changes.append(("nic.%s/%d" % (key, idx), val)) |
3394 | 3408 |
|
3395 | 3409 |
if self.op.hotplug: |
3396 |
self._HotplugDevice(constants.HOTPLUG_ACTION_MODIFY, |
|
3397 |
constants.HOTPLUG_TARGET_NIC, |
|
3398 |
nic, None, idx) |
|
3410 |
msg = self._HotplugDevice(constants.HOTPLUG_ACTION_MODIFY, |
|
3411 |
constants.HOTPLUG_TARGET_NIC, |
|
3412 |
nic, None, idx) |
|
3413 |
changes.append(("nic/%d" % idx, msg)) |
|
3399 | 3414 |
|
3400 | 3415 |
return changes |
3401 | 3416 |
|
3402 | 3417 |
def _RemoveNic(self, idx, nic, _): |
3403 | 3418 |
if self.op.hotplug: |
3404 |
self._HotplugDevice(constants.HOTPLUG_ACTION_REMOVE, |
|
3405 |
constants.HOTPLUG_TARGET_NIC, |
|
3406 |
nic, None, idx) |
|
3419 |
return self._HotplugDevice(constants.HOTPLUG_ACTION_REMOVE,
|
|
3420 |
constants.HOTPLUG_TARGET_NIC,
|
|
3421 |
nic, None, idx)
|
|
3407 | 3422 |
|
3408 | 3423 |
def Exec(self, feedback_fn): |
3409 | 3424 |
"""Modifies an instance. |
b/man/gnt-instance.rst | ||
---|---|---|
1206 | 1206 |
If ``--ignore-ipolicy`` is given any instance policy violations occuring |
1207 | 1207 |
during this operation are ignored. |
1208 | 1208 |
|
1209 |
If ``--hotplug`` is given any disk and nic modifications will take
|
|
1209 |
If ``--hotplug`` is given any disk and NIC modifications will take
|
|
1210 | 1210 |
effect without the need of actual reboot. Please note that this feature |
1211 |
is currently supported only for KVM hypervisor and for versions greater |
|
1212 |
than 1.0. |
|
1211 |
is currently supported only for KVM hypervisor and there are some |
|
1212 |
restrictions: a) KVM versions >= 1.0 support it b) instances with chroot |
|
1213 |
or uid pool security model do not support disk hotplug c) RBD disks with |
|
1214 |
userspace access mode can not be hotplugged (yet) d) if hotplug fails |
|
1215 |
(for any reason) a warning is printed but execution is continued e) |
|
1216 |
for existing NIC modification interactive verification is needed unless |
|
1217 |
``--force`` option is passed. |
|
1213 | 1218 |
|
1214 | 1219 |
See **ganeti**\(7) for a description of ``--submit`` and other common |
1215 | 1220 |
options. |
b/qa/qa_instance.py | ||
---|---|---|
538 | 538 |
qa_config.TestEnabled("instance-device-hotplug"): |
539 | 539 |
args.extend([ |
540 | 540 |
["--net", "-1:add", "--hotplug"], |
541 |
["--net", "-1:modify,mac=aa:bb:cc:dd:ee:ff", "--hotplug"], |
|
541 |
["--net", "-1:modify,mac=aa:bb:cc:dd:ee:ff", "--hotplug", "--force"],
|
|
542 | 542 |
["--net", "-1:remove", "--hotplug"], |
543 | 543 |
["--disk", "-1:add,size=1G", "--hotplug"], |
544 | 544 |
["--disk", "-1:remove", "--hotplug"], |
Also available in: Unified diff