raise NotImplementedError
@staticmethod
+ def _WriteConfigFileStatic(instance_name, data):
+ """Write the Xen config file for the instance.
+
+ This version of the function just writes the config file from static data.
+
+ """
+ utils.WriteFile("/etc/xen/%s" % instance_name, data=data)
+
+ @staticmethod
+ def _ReadConfigFile(instance_name):
+ """Returns the contents of the instance config file.
+
+ """
+ try:
+ file_content = utils.ReadFile("/etc/xen/%s" % instance_name)
+ except EnvironmentError, err:
+ raise errors.HypervisorError("Failed to load Xen config file: %s" % err)
+ return file_content
+
+ @staticmethod
def _RemoveConfigFile(instance_name):
"""Remove the xen configuration file.
return result
- @staticmethod
- def GetShellCommandForConsole(instance):
+ @classmethod
+ def GetShellCommandForConsole(cls, instance):
"""Return a command for connecting to the console of an instance.
"""
# directly export their info (currently HVM will just sed this info)
namespace = ["sd" + chr(i + ord('a')) for i in range(24)]
for sd_name, (cfdev, dev_path) in zip(namespace, block_devices):
+ if cfdev.mode == constants.DISK_RDWR:
+ mode = "w"
+ else:
+ mode = "r"
if cfdev.dev_type == constants.LD_FILE:
- line = "'%s:%s,%s,w'" % (FILE_DRIVER_MAP[cfdev.physical_id[0]],
- dev_path, sd_name)
+ line = "'%s:%s,%s,%s'" % (FILE_DRIVER_MAP[cfdev.physical_id[0]],
+ dev_path, sd_name, mode)
else:
- line = "'phy:%s,%s,w'" % (dev_path, sd_name)
+ line = "'phy:%s,%s,%s'" % (dev_path, sd_name, mode)
disk_data.append(line)
return disk_data
- def MigrateInstance(self, instance, target, live):
- """Migrate an instance to a target node.
+ def MigrationInfo(self, instance):
+ """Get instance information to perform a migration.
+
+ @type instance: L{objects.Instance}
+ @param instance: instance to be migrated
+ @rtype: string
+ @return: content of the xen config file
+
+ """
+ return self._ReadConfigFile(instance.name)
+
+ def AcceptInstance(self, instance, info, target):
+ """Prepare to accept an instance.
- Arguments:
- - instance: the name of the instance
- - target: the ip of the target node
- - live: whether to do live migration or not
+ @type instance: L{objects.Instance}
+ @param instance: instance to be accepted
+ @type info: string
+ @param info: content of the xen config file on the source node
+ @type target: string
+ @param target: target host (usually ip), on this node
- Returns: none, errors will be signaled by exception.
+ """
+ pass
+
+ def FinalizeMigration(self, instance, info, success):
+ """Finalize an instance migration.
+
+ After a successful migration we write the xen config file.
+ We do nothing on a failure, as we did not change anything at accept time.
+
+ @type instance: L{objects.Instance}
+ @param instance: instance whose migration is being aborted
+ @type info: string
+ @param info: content of the xen config file on the source node
+ @type success: boolean
+ @param success: whether the migration was a success or a failure
+
+ """
+ if success:
+ self._WriteConfigFileStatic(instance.name, info)
+
+ def MigrateInstance(self, instance, target, live):
+ """Migrate an instance to a target node.
The migration will not be attempted if the instance is not
currently running.
+ @type instance: string
+ @param instance: instance name
+ @type target: string
+ @param target: ip address of the target node
+ @type live: boolean
+ @param live: perform a live migration
+
"""
if self.GetInstanceInfo(instance) is None:
raise errors.HypervisorError("Instance not running, cannot migrate")
# remove old xen file after migration succeeded
try:
self._RemoveConfigFile(instance)
- except EnvironmentError, err:
- logger.Error("Failure while removing instance config file: %s" %
- str(err))
+ except EnvironmentError:
+ logging.exception("Failure while removing instance config file")
class XenPvmHypervisor(XenHypervisor):
PARAMETERS = [
constants.HV_KERNEL_PATH,
constants.HV_INITRD_PATH,
+ constants.HV_ROOT_PATH,
]
@classmethod
raise errors.HypervisorError("Need a kernel for the instance")
if not os.path.isabs(hvparams[constants.HV_KERNEL_PATH]):
- raise errors.HypervisorError("The kernel path must an absolute path")
+ raise errors.HypervisorError("The kernel path must be an absolute path")
+
+ if not hvparams[constants.HV_ROOT_PATH]:
+ raise errors.HypervisorError("Need a root partition for the instance")
if hvparams[constants.HV_INITRD_PATH]:
if not os.path.isabs(hvparams[constants.HV_INITRD_PATH]):
- raise errors.HypervisorError("The initrd path must an absolute path"
+ raise errors.HypervisorError("The initrd path must be an absolute path"
", if defined")
def ValidateParameters(self, hvparams):
config.write("disk = [%s]\n" % ",".join(
cls._GetConfigFileDiskData(instance.disk_template,
block_devices)))
- config.write("root = '/dev/sda ro'\n")
+
+ rpath = instance.hvparams[constants.HV_ROOT_PATH]
+ config.write("root = '%s ro'\n" % rpath)
config.write("on_poweroff = 'destroy'\n")
config.write("on_reboot = 'restart'\n")
config.write("on_crash = 'restart'\n")
# just in case it exists
utils.RemoveFile("/etc/xen/auto/%s" % instance.name)
try:
- f = open("/etc/xen/%s" % instance.name, "w")
- try:
- f.write(config.getvalue())
- finally:
- f.close()
- except IOError, err:
- raise errors.OpExecError("Cannot write Xen instance confile"
- " file /etc/xen/%s: %s" % (instance.name, err))
+ utils.WriteFile("/etc/xen/%s" % instance.name,
+ data=config.getvalue())
+ except EnvironmentError, err:
+ raise errors.HypervisorError("Cannot write Xen instance confile"
+ " file /etc/xen/%s: %s" %
+ (instance.name, err))
+
return True
config.write("vncunused = 1\n")
try:
- password_file = open(constants.VNC_PASSWORD_FILE, "r")
- try:
- password = password_file.readline()
- finally:
- password_file.close()
- except IOError:
- raise errors.OpExecError("failed to open VNC password file %s " %
- constants.VNC_PASSWORD_FILE)
+ password = utils.ReadFile(constants.VNC_PASSWORD_FILE)
+ except EnvironmentError, err:
+ raise errors.HypervisorError("Failed to open VNC password file %s: %s" %
+ (constants.VNC_PASSWORD_FILE, err))
config.write("vncpasswd = '%s'\n" % password.rstrip())
# just in case it exists
utils.RemoveFile("/etc/xen/auto/%s" % instance.name)
try:
- f = open("/etc/xen/%s" % instance.name, "w")
- try:
- f.write(config.getvalue())
- finally:
- f.close()
- except IOError, err:
- raise errors.OpExecError("Cannot write Xen instance confile"
- " file /etc/xen/%s: %s" % (instance.name, err))
+ utils.WriteFile("/etc/xen/%s" % instance.name,
+ data=config.getvalue())
+ except EnvironmentError, err:
+ raise errors.HypervisorError("Cannot write Xen instance confile"
+ " file /etc/xen/%s: %s" %
+ (instance.name, err))
+
return True