46 |
46 |
from ganeti import ssconf
|
47 |
47 |
|
48 |
48 |
|
|
49 |
class RPCFail(Exception):
|
|
50 |
"""Class denoting RPC failure.
|
|
51 |
|
|
52 |
Its argument is the error message.
|
|
53 |
|
|
54 |
"""
|
|
55 |
|
|
56 |
def _Fail(msg, *args, **kwargs):
|
|
57 |
"""Log an error and the raise an RPCFail exception.
|
|
58 |
|
|
59 |
This exception is then handled specially in the ganeti daemon and
|
|
60 |
turned into a 'failed' return type. As such, this function is a
|
|
61 |
useful shortcut for logging the error and returning it to the master
|
|
62 |
daemon.
|
|
63 |
|
|
64 |
@type msg: string
|
|
65 |
@param msg: the text of the exception
|
|
66 |
@raise RPCFail
|
|
67 |
|
|
68 |
"""
|
|
69 |
if args:
|
|
70 |
msg = msg % args
|
|
71 |
if "exc" in kwargs and kwargs["exc"]:
|
|
72 |
logging.exception(msg)
|
|
73 |
else:
|
|
74 |
logging.error(msg)
|
|
75 |
raise RPCFail(msg)
|
|
76 |
|
|
77 |
|
49 |
78 |
def _GetConfig():
|
50 |
79 |
"""Simple wrapper to return a SimpleStore.
|
51 |
80 |
|
... | ... | |
260 |
289 |
priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.GANETI_RUNAS,
|
261 |
290 |
mkdir=True)
|
262 |
291 |
except errors.OpExecError, err:
|
263 |
|
msg = "Error while processing user ssh files"
|
264 |
|
logging.exception(msg)
|
265 |
|
return (False, "%s: %s" % (msg, err))
|
|
292 |
_Fail("Error while processing user ssh files: %s", err, exc=True)
|
266 |
293 |
|
267 |
294 |
for name, content in [(priv_key, sshkey), (pub_key, sshpub)]:
|
268 |
295 |
utils.WriteFile(name, data=content, mode=0600)
|
... | ... | |
884 |
911 |
hyper = hypervisor.GetHypervisor(instance.hypervisor)
|
885 |
912 |
hyper.StartInstance(instance, block_devices)
|
886 |
913 |
except errors.BlockDeviceError, err:
|
887 |
|
logging.exception("Failed to start instance")
|
888 |
|
return (False, "Block device error: %s" % str(err))
|
|
914 |
_Fail("Block device error: %s", err, exc=True)
|
889 |
915 |
except errors.HypervisorError, err:
|
890 |
|
logging.exception("Failed to start instance")
|
891 |
916 |
_RemoveBlockDevLinks(instance.name, instance.disks)
|
892 |
|
return (False, "Hypervisor error: %s" % str(err))
|
|
917 |
_Fail("Hypervisor error: %s", err, exc=True)
|
893 |
918 |
|
894 |
919 |
return (True, "Instance started successfully")
|
895 |
920 |
|
... | ... | |
915 |
940 |
try:
|
916 |
941 |
hyper.StopInstance(instance)
|
917 |
942 |
except errors.HypervisorError, err:
|
918 |
|
msg = "Failed to stop instance %s: %s" % (instance.name, err)
|
919 |
|
logging.error(msg)
|
920 |
|
return (False, msg)
|
|
943 |
_Fail("Failed to stop instance %s: %s", instance.name, err)
|
921 |
944 |
|
922 |
945 |
# test every 10secs for 2min
|
923 |
946 |
|
... | ... | |
934 |
957 |
try:
|
935 |
958 |
hyper.StopInstance(instance, force=True)
|
936 |
959 |
except errors.HypervisorError, err:
|
937 |
|
msg = "Failed to force stop instance %s: %s" % (instance.name, err)
|
938 |
|
logging.error(msg)
|
939 |
|
return (False, msg)
|
|
960 |
_Fail("Failed to force stop instance %s: %s", instance.name, err)
|
940 |
961 |
|
941 |
962 |
time.sleep(1)
|
942 |
963 |
if instance.name in GetInstanceList([hv_name]):
|
943 |
|
msg = ("Could not shutdown instance %s even by destroy" %
|
944 |
|
instance.name)
|
945 |
|
logging.error(msg)
|
946 |
|
return (False, msg)
|
|
964 |
_Fail("Could not shutdown instance %s even by destroy", instance.name)
|
947 |
965 |
|
948 |
966 |
_RemoveBlockDevLinks(instance.name, instance.disks)
|
949 |
967 |
|
... | ... | |
972 |
990 |
running_instances = GetInstanceList([instance.hypervisor])
|
973 |
991 |
|
974 |
992 |
if instance.name not in running_instances:
|
975 |
|
msg = "Cannot reboot instance %s that is not running" % instance.name
|
976 |
|
logging.error(msg)
|
977 |
|
return (False, msg)
|
|
993 |
_Fail("Cannot reboot instance %s that is not running", instance.name)
|
978 |
994 |
|
979 |
995 |
hyper = hypervisor.GetHypervisor(instance.hypervisor)
|
980 |
996 |
if reboot_type == constants.INSTANCE_REBOOT_SOFT:
|
981 |
997 |
try:
|
982 |
998 |
hyper.RebootInstance(instance)
|
983 |
999 |
except errors.HypervisorError, err:
|
984 |
|
msg = "Failed to soft reboot instance %s: %s" % (instance.name, err)
|
985 |
|
logging.error(msg)
|
986 |
|
return (False, msg)
|
|
1000 |
_Fail("Failed to soft reboot instance %s: %s", instance.name, err)
|
987 |
1001 |
elif reboot_type == constants.INSTANCE_REBOOT_HARD:
|
988 |
1002 |
try:
|
989 |
1003 |
stop_result = InstanceShutdown(instance)
|
... | ... | |
991 |
1005 |
return stop_result
|
992 |
1006 |
return StartInstance(instance)
|
993 |
1007 |
except errors.HypervisorError, err:
|
994 |
|
msg = "Failed to hard reboot instance %s: %s" % (instance.name, err)
|
995 |
|
logging.error(msg)
|
996 |
|
return (False, msg)
|
|
1008 |
_Fail("Failed to hard reboot instance %s: %s", instance.name, err)
|
997 |
1009 |
else:
|
998 |
|
return (False, "Invalid reboot_type received: %s" % (reboot_type,))
|
|
1010 |
_Fail("Invalid reboot_type received: %s", reboot_type)
|
999 |
1011 |
|
1000 |
1012 |
return (True, "Reboot successful")
|
1001 |
1013 |
|
... | ... | |
1011 |
1023 |
try:
|
1012 |
1024 |
info = hyper.MigrationInfo(instance)
|
1013 |
1025 |
except errors.HypervisorError, err:
|
1014 |
|
msg = "Failed to fetch migration information"
|
1015 |
|
logging.exception(msg)
|
1016 |
|
return (False, '%s: %s' % (msg, err))
|
|
1026 |
_Fail("Failed to fetch migration information: %s", err, exc=True)
|
1017 |
1027 |
return (True, info)
|
1018 |
1028 |
|
1019 |
1029 |
|
... | ... | |
1032 |
1042 |
try:
|
1033 |
1043 |
hyper.AcceptInstance(instance, info, target)
|
1034 |
1044 |
except errors.HypervisorError, err:
|
1035 |
|
msg = "Failed to accept instance"
|
1036 |
|
logging.exception(msg)
|
1037 |
|
return (False, '%s: %s' % (msg, err))
|
|
1045 |
_Fail("Failed to accept instance: %s", err, exc=True)
|
1038 |
1046 |
return (True, "Accept successfull")
|
1039 |
1047 |
|
1040 |
1048 |
|
... | ... | |
1053 |
1061 |
try:
|
1054 |
1062 |
hyper.FinalizeMigration(instance, info, success)
|
1055 |
1063 |
except errors.HypervisorError, err:
|
1056 |
|
msg = "Failed to finalize migration"
|
1057 |
|
logging.exception(msg)
|
1058 |
|
return (False, '%s: %s' % (msg, err))
|
|
1064 |
_Fail("Failed to finalize migration: %s", err, exc=True)
|
1059 |
1065 |
return (True, "Migration Finalized")
|
1060 |
1066 |
|
1061 |
1067 |
|
... | ... | |
1080 |
1086 |
try:
|
1081 |
1087 |
hyper.MigrateInstance(instance.name, target, live)
|
1082 |
1088 |
except errors.HypervisorError, err:
|
1083 |
|
msg = "Failed to migrate instance"
|
1084 |
|
logging.exception(msg)
|
1085 |
|
return (False, "%s: %s" % (msg, err))
|
|
1089 |
_Fail("Failed to migrate instance: %s", err, exc=True)
|
1086 |
1090 |
return (True, "Migration successfull")
|
1087 |
1091 |
|
1088 |
1092 |
|
... | ... | |
1113 |
1117 |
try:
|
1114 |
1118 |
crdev = _RecursiveAssembleBD(child, owner, on_primary)
|
1115 |
1119 |
except errors.BlockDeviceError, err:
|
1116 |
|
errmsg = "Can't assemble device %s: %s" % (child, err)
|
1117 |
|
logging.error(errmsg)
|
1118 |
|
return False, errmsg
|
|
1120 |
_Fail("Can't assemble device %s: %s", child, err)
|
1119 |
1121 |
if on_primary or disk.AssembleOnSecondary():
|
1120 |
1122 |
# we need the children open in case the device itself has to
|
1121 |
1123 |
# be assembled
|
1122 |
1124 |
try:
|
1123 |
1125 |
crdev.Open()
|
1124 |
1126 |
except errors.BlockDeviceError, err:
|
1125 |
|
errmsg = "Can't make child '%s' read-write: %s" % (child, err)
|
1126 |
|
logging.error(errmsg)
|
1127 |
|
return False, errmsg
|
|
1127 |
_Fail("Can't make child '%s' read-write: %s", child, err)
|
1128 |
1128 |
clist.append(crdev)
|
1129 |
1129 |
|
1130 |
1130 |
try:
|
1131 |
1131 |
device = bdev.Create(disk.dev_type, disk.physical_id, clist, size)
|
1132 |
1132 |
except errors.BlockDeviceError, err:
|
1133 |
|
return False, "Can't create block device: %s" % str(err)
|
|
1133 |
_Fail("Can't create block device: %s", err)
|
1134 |
1134 |
|
1135 |
1135 |
if on_primary or disk.AssembleOnSecondary():
|
1136 |
1136 |
try:
|
1137 |
1137 |
device.Assemble()
|
1138 |
1138 |
except errors.BlockDeviceError, err:
|
1139 |
|
errmsg = ("Can't assemble device after creation, very"
|
1140 |
|
" unusual event: %s" % str(err))
|
1141 |
|
logging.error(errmsg)
|
1142 |
|
return False, errmsg
|
|
1139 |
_Fail("Can't assemble device after creation, unusual event: %s", err)
|
1143 |
1140 |
device.SetSyncSpeed(constants.SYNC_SPEED)
|
1144 |
1141 |
if on_primary or disk.OpenOnSecondary():
|
1145 |
1142 |
try:
|
1146 |
1143 |
device.Open(force=True)
|
1147 |
1144 |
except errors.BlockDeviceError, err:
|
1148 |
|
errmsg = ("Can't make device r/w after creation, very"
|
1149 |
|
" unusual event: %s" % str(err))
|
1150 |
|
logging.error(errmsg)
|
1151 |
|
return False, errmsg
|
|
1145 |
_Fail("Can't make device r/w after creation, unusual event: %s", err)
|
1152 |
1146 |
DevCacheManager.UpdateCache(device.dev_path, owner,
|
1153 |
1147 |
on_primary, disk.iv_name)
|
1154 |
1148 |
|
... | ... | |
1326 |
1320 |
"""
|
1327 |
1321 |
parent_bdev = _RecursiveFindBD(parent_cdev)
|
1328 |
1322 |
if parent_bdev is None:
|
1329 |
|
msg = "Can't find parent device '%s' in add children" % str(parent_cdev)
|
1330 |
|
logging.error("BlockdevAddchildren: %s", msg)
|
1331 |
|
return (False, msg)
|
|
1323 |
_Fail("Can't find parent device '%s' in add children", parent_cdev)
|
1332 |
1324 |
new_bdevs = [_RecursiveFindBD(disk) for disk in new_cdevs]
|
1333 |
1325 |
if new_bdevs.count(None) > 0:
|
1334 |
|
msg = "Can't find new device(s) to add: %s:%s" % (new_bdevs, new_cdevs)
|
1335 |
|
logging.error(msg)
|
1336 |
|
return (False, msg)
|
|
1326 |
_Fail("Can't find new device(s) to add: %s:%s", new_bdevs, new_cdevs)
|
1337 |
1327 |
parent_bdev.AddChildren(new_bdevs)
|
1338 |
1328 |
return (True, None)
|
1339 |
1329 |
|
... | ... | |
1351 |
1341 |
"""
|
1352 |
1342 |
parent_bdev = _RecursiveFindBD(parent_cdev)
|
1353 |
1343 |
if parent_bdev is None:
|
1354 |
|
msg = "Can't find parent device '%s' in remove children" % str(parent_cdev)
|
1355 |
|
logging.error(msg)
|
1356 |
|
return (False, msg)
|
|
1344 |
_Fail("Can't find parent device '%s' in remove children", parent_cdev)
|
1357 |
1345 |
devs = []
|
1358 |
1346 |
for disk in new_cdevs:
|
1359 |
1347 |
rpath = disk.StaticDevPath()
|
1360 |
1348 |
if rpath is None:
|
1361 |
1349 |
bd = _RecursiveFindBD(disk)
|
1362 |
1350 |
if bd is None:
|
1363 |
|
msg = "Can't find device %s while removing children" % (disk,)
|
1364 |
|
logging.error(msg)
|
1365 |
|
return (False, msg)
|
|
1351 |
_Fail("Can't find device %s while removing children", disk)
|
1366 |
1352 |
else:
|
1367 |
1353 |
devs.append(bd.dev_path)
|
1368 |
1354 |
else:
|
... | ... | |
1429 |
1415 |
try:
|
1430 |
1416 |
rbd = _RecursiveFindBD(disk)
|
1431 |
1417 |
except errors.BlockDeviceError, err:
|
1432 |
|
return (False, str(err))
|
|
1418 |
_Fail("Failed to find device: %s", err, exc=True)
|
1433 |
1419 |
if rbd is None:
|
1434 |
1420 |
return (True, None)
|
1435 |
1421 |
return (True, (rbd.dev_path, rbd.major, rbd.minor) + rbd.GetSyncStatus())
|
... | ... | |
1461 |
1447 |
|
1462 |
1448 |
"""
|
1463 |
1449 |
if not os.path.isabs(file_name):
|
1464 |
|
err = "Filename passed to UploadFile is not absolute: '%s'" % file_name
|
1465 |
|
logging.error(err)
|
1466 |
|
return (False, err)
|
|
1450 |
_Fail("Filename passed to UploadFile is not absolute: '%s'", file_name)
|
1467 |
1451 |
|
1468 |
1452 |
allowed_files = set([
|
1469 |
1453 |
constants.CLUSTER_CONF_FILE,
|
... | ... | |
1479 |
1463 |
allowed_files.update(hv_class.GetAncillaryFiles())
|
1480 |
1464 |
|
1481 |
1465 |
if file_name not in allowed_files:
|
1482 |
|
err = "Filename passed to UploadFile not in allowed upload targets: '%s'" \
|
1483 |
|
% file_name
|
1484 |
|
logging.error(err)
|
1485 |
|
return (False, err)
|
|
1466 |
_Fail("Filename passed to UploadFile not in allowed upload targets: '%s'",
|
|
1467 |
file_name)
|
1486 |
1468 |
|
1487 |
1469 |
raw_data = _Decompress(data)
|
1488 |
1470 |
|
... | ... | |
1726 |
1708 |
try:
|
1727 |
1709 |
r_dev.Grow(amount)
|
1728 |
1710 |
except errors.BlockDeviceError, err:
|
1729 |
|
return False, str(err)
|
|
1711 |
_Fail("Failed to grow block device: %s", err, exc=True)
|
1730 |
1712 |
|
1731 |
1713 |
return True, None
|
1732 |
1714 |
|
... | ... | |
2269 |
2251 |
for cf in disks:
|
2270 |
2252 |
rd = _RecursiveFindBD(cf)
|
2271 |
2253 |
if rd is None:
|
2272 |
|
return (False, "Can't find device %s" % cf)
|
|
2254 |
_Fail("Can't find device %s", cf)
|
2273 |
2255 |
bdevs.append(rd)
|
2274 |
2256 |
|
2275 |
2257 |
msg = []
|
... | ... | |
2360 |
2342 |
try:
|
2361 |
2343 |
rd.DisconnectNet()
|
2362 |
2344 |
except errors.BlockDeviceError, err:
|
2363 |
|
logging.exception("Failed to go into standalone mode")
|
2364 |
|
return (False, "Can't change network configuration: %s" % str(err))
|
|
2345 |
_Fail("Can't change network configuration to standalone mode: %s",
|
|
2346 |
err, exc=True)
|
2365 |
2347 |
return (True, "All disks are now disconnected")
|
2366 |
2348 |
|
2367 |
2349 |
|
... | ... | |
2378 |
2360 |
try:
|
2379 |
2361 |
_SymlinkBlockDev(instance_name, rd.dev_path, idx)
|
2380 |
2362 |
except EnvironmentError, err:
|
2381 |
|
return (False, "Can't create symlink: %s" % str(err))
|
|
2363 |
_Fail("Can't create symlink: %s", err)
|
2382 |
2364 |
# reconnect disks, switch to new master configuration and if
|
2383 |
2365 |
# needed primary mode
|
2384 |
2366 |
for rd in bdevs:
|
2385 |
2367 |
try:
|
2386 |
2368 |
rd.AttachNet(multimaster)
|
2387 |
2369 |
except errors.BlockDeviceError, err:
|
2388 |
|
return (False, "Can't change network configuration: %s" % str(err))
|
|
2370 |
_Fail("Can't change network configuration: %s", err)
|
2389 |
2371 |
# wait until the disks are connected; we need to retry the re-attach
|
2390 |
2372 |
# if the device becomes standalone, as this might happen if the one
|
2391 |
2373 |
# node disconnects and reconnects in a different mode before the
|
... | ... | |
2407 |
2389 |
try:
|
2408 |
2390 |
rd.ReAttachNet(multimaster)
|
2409 |
2391 |
except errors.BlockDeviceError, err:
|
2410 |
|
return (False, "Can't change network configuration: %s" % str(err))
|
|
2392 |
_Fail("Can't change network configuration: %s", err)
|
2411 |
2393 |
if all_connected:
|
2412 |
2394 |
break
|
2413 |
2395 |
time.sleep(sleep_time)
|
... | ... | |
2420 |
2402 |
try:
|
2421 |
2403 |
rd.Open()
|
2422 |
2404 |
except errors.BlockDeviceError, err:
|
2423 |
|
return (False, "Can't change to primary mode: %s" % str(err))
|
|
2405 |
_Fail("Can't change to primary mode: %s", err)
|
2424 |
2406 |
if multimaster:
|
2425 |
2407 |
msg = "multi-master and primary"
|
2426 |
2408 |
else:
|