def parseExistingInstallation(self): results = {} if len(self.nodelist.getElementsByTagName('existing-installation')) == 0: raise AnswerfileError, "No existing installation specified." ei = getText(self.nodelist.getElementsByTagName('existing-installation')[0].childNodes) if ei.startswith('iscsi:'): # ei is a rfc4173 spec identifying a LUN in the iBFT. # We should be logged into this already. # Convert this spec into a disk location. disk = diskutil.rfc4173_to_disk(ei) else: disk = normalize_disk(ei) # If answerfile names a multipath replace with the master! master = disktools.getMpathMaster(disk) if master: disk = master results['primary-disk'] = disk installations = product.findXenSourceProducts() installations = filter(lambda x: x.primary_disk == disk or diskutil.idFromPartition(x.primary_disk) == disk, installations) if len(installations) == 0: raise AnswerfileError, "Could not locate the installation specified to be reinstalled." elif len(installations) > 1: xelogging.log("Warning: multiple paths detected - recommend use of --device_mapper_multipath=yes") xelogging.log("Warning: selecting 1st path from %s" % str(map(lambda x: x.primary_disk, installations))) results['installation-to-overwrite'] = installations[0] return results
def parseUpgrade(self): results = {} results['install-type'] = constants.INSTALL_TYPE_REINSTALL results.update(self.parseExistingInstallation()) results['preserve-settings'] = True results['backup-existing-installation'] = True target_nodes = self.nodelist.getElementsByTagName('primary-disk') if len(target_nodes) == 1: node_text = getText(target_nodes[0].childNodes) if node_text.startswith('iscsi:'): # node_text is an rfc4173 spec identifying a LUN in the # iBFT. We should be logged into this already. Convert # this spec into a disk location. disk = diskutil.rfc4173_to_disk(node_text) else: disk = normalize_disk(node_text) # If answerfile names a multipath replace with the master! master = disktools.getMpathMaster(disk) if master: disk = master results['primary-disk'] = disk results.update(self.parseSource()) results.update(self.parseDriverSource()) results.update(self.parseBootloader()) return results
def normalize_disk(disk): if disk.startswith('iscsi:'): # An rfc4173 spec identifying a LUN in the iBFT. We # should be logged into this already. Convert this spec into a # disk location. return diskutil.rfc4173_to_disk(disk) if not disk.startswith('/dev/'): disk = '/dev/' + disk return diskutil.partitionFromId(disk)
def parseFreshInstall(self): results = {} results['install-type'] = constants.INSTALL_TYPE_FRESH results['preserve-settings'] = False # storage type (lvm or ext): srtype_node = self.nodelist.getAttribute("srtype") if srtype_node in ['', 'lvm']: srtype = constants.SR_TYPE_LVM elif srtype_node in ['ext']: srtype = constants.SR_TYPE_EXT else: raise AnswerfileError, "Specified SR Type unknown. Should be 'lvm' or 'ext'." results['sr-type'] = srtype # initial-partitions: results['initial-partitions'] = [] init_part_nodes = self.nodelist.getElementsByTagName('initial-partitions') if len(init_part_nodes) == 1: for part_node in init_part_nodes[0].getElementsByTagName('partition'): try: part = {} for k in ('number', 'size', 'id'): part[k] = int(part_node.getAttribute(k), 0) results['initial-partitions'].append(part) except: pass # zap-utility-partitions: do not preserve UP at install. # # Dell 11G servers (and later) only use the UP for factory install of XS but don't # need it thereafter as they have a seperate utility flash drive for diagnostics. # Installs to Dell 10G servers, however, should not zap the UP as they don't have a flash # drive and need the UP persisted for diags. If UP present, it boots 1st & chainloads XS. nodes = self.nodelist.getElementsByTagName('zap-utility-partitions') results['zap-utility-partitions'] = (len(nodes) > 0) # primary-disk: pd = self.nodelist.getElementsByTagName('primary-disk') pd_text = getText(pd[0].childNodes) if pd_text.startswith('iscsi:'): # pd_text is an rfc4173 spec identifying a LUN in the iBFT. We # should be logged into this already. Convert this spec into a # disk location. disk = diskutil.rfc4173_to_disk(pd_text) else: disk = normalize_disk(pd_text) # If we're using multipath and the answerfile names a multipath # slave, then we want to install to the master! master = disktools.getMpathMaster(disk) if master: disk = master results['primary-disk'] = disk pd_has_guest_storage = pd[0].getAttribute("gueststorage").lower() in ["", "yes", "true"] results['sr-at-end'] = pd[0].getAttribute("sr-at-end").lower() in ["", "yes", "true"] results['preserve-first-partition'] = pd[0].getAttribute("preserve-first-partition").lower() in ["yes", "true"] # guest-disks: results['guest-disks'] = [] if pd_has_guest_storage: results['guest-disks'].append(results['primary-disk']) for disknode in self.nodelist.getElementsByTagName('guest-disk'): disk = normalize_disk(getText(disknode.childNodes)) # Replace references to multipath slaves with references to their multipath masters master = disktools.getMpathMaster(disk) if master: # CA-38329: disallow device mapper nodes (except primary disk) as these won't exist # at XenServer boot and therefore cannot be added as physical volumes to Local SR. # Also, since the DM nodes are multipathed SANs it doesn't make sense to include them # in the "Local" SR. if master != results['primary-disk']: raise AnswerfileError, "Answerfile specifies non-local disk %s to add to Local SR" % disk disk = master results['guest-disks'].append(disk) results.update(self.parseSource()) results.update(self.parseDriverSource()) results.update(self.parseInterfaces()) results.update(self.parseRootPassword()) results.update(self.parseNSConfig()) results.update(self.parseTimeConfig()) results.update(self.parseKeymap()) results.update(self.parseBootloader()) return results