def editLogicalVolume(self, logrequest, isNew=0): if isNew: tstr = _("Make Logical Volume") else: try: tstr = _("Edit Logical Volume: %s") % ( logrequest.logicalVolumeName, ) except: tstr = _("Edit Logical Volume") dialog = gtk.Dialog(tstr, self.parent) gui.addFrame(dialog) dialog.add_button('gtk-cancel', 2) dialog.add_button('gtk-ok', 1) dialog.set_position(gtk.WIN_POS_CENTER) maintable = gtk.Table() maintable.set_row_spacings(5) maintable.set_col_spacings(5) row = 0 lbl = createAlignedLabel(_("_Mount Point:")) maintable.attach(lbl, 0, 1, row, row + 1) mountCombo = createMountPointCombo(logrequest, excludeMountPoints=["/boot"]) lbl.set_mnemonic_widget(mountCombo.entry) maintable.attach(mountCombo, 1, 2, row, row + 1) row = row + 1 if not logrequest or not logrequest.getPreExisting(): lbl = createAlignedLabel(_("_File System Type:")) maintable.attach(lbl, 0, 1, row, row + 1) (newfstype, newfstypeMenu) = createFSTypeMenu(logrequest.fstype, fstypechangeCB, mountCombo, ignorefs=[ "software RAID", "physical volume (LVM)", "vfat", "PPC PReP Boot" ]) lbl.set_mnemonic_widget(newfstype) else: maintable.attach( createAlignedLabel(_("Original File System Type:")), 0, 1, row, row + 1) if logrequest.origfstype and logrequest.origfstype.getName(): newfstype = gtk.Label(logrequest.origfstype.getName()) else: newfstype = gtk.Label(_("Unknown")) maintable.attach(newfstype, 1, 2, row, row + 1) row = row + 1 if not logrequest or not logrequest.getPreExisting(): lbl = createAlignedLabel(_("_Logical Volume Name:")) lvnameEntry = gtk.Entry(16) lbl.set_mnemonic_widget(lvnameEntry) if logrequest and logrequest.logicalVolumeName: lvnameEntry.set_text(logrequest.logicalVolumeName) else: lvnameEntry.set_text(lvm.createSuggestedLVName( self.logvolreqs)) else: lbl = createAlignedLabel(_("Logical Volume Name:")) lvnameEntry = gtk.Label(logrequest.logicalVolumeName) maintable.attach(lbl, 0, 1, row, row + 1) maintable.attach(lvnameEntry, 1, 2, row, row + 1) row = row + 1 if not logrequest or not logrequest.getPreExisting(): lbl = createAlignedLabel(_("_Size (MB):")) sizeEntry = gtk.Entry(16) lbl.set_mnemonic_widget(sizeEntry) if logrequest: sizeEntry.set_text("%g" % (logrequest.getActualSize( self.partitions, self.diskset), )) else: lbl = createAlignedLabel(_("Size (MB):")) sizeEntry = gtk.Label(str(logrequest.size)) maintable.attach(lbl, 0, 1, row, row + 1) maintable.attach(sizeEntry, 1, 2, row, row + 1) row = row + 1 if not logrequest or not logrequest.getPreExisting(): pesize = self.peOptionMenu.get_active().get_data("value") (tspace, uspace, fspace) = self.computeSpaceValues(usepe=pesize) maxlv = min(lvm.getMaxLVSize(pesize), fspace) # add in size of current logical volume if it has a size if logrequest and not isNew: maxlv = maxlv + logrequest.getActualSize( self.partitions, self.diskset) maxlabel = createAlignedLabel(_("(Max size is %s MB)") % (maxlv, )) maintable.attach(maxlabel, 1, 2, row, row + 1) self.fsoptionsDict = {} if logrequest.getPreExisting(): (row, self.fsoptionsDict) = createPreExistFSOptionSection( logrequest, maintable, row, mountCombo, showbadblocks=0, ignorefs=["software RAID", "physical volume (LVM)", "vfat"]) dialog.vbox.pack_start(maintable) dialog.show_all() while 1: rc = dialog.run() if rc == 2: dialog.destroy() return if not logrequest or not logrequest.getPreExisting(): fsystem = newfstypeMenu.get_active().get_data("type") format = 1 migrate = 0 else: if self.fsoptionsDict.has_key("formatrb"): formatrb = self.fsoptionsDict["formatrb"] else: formatrb = None if formatrb: format = formatrb.get_active() if format: fsystem = self.fsoptionsDict["fstypeMenu"].get_active( ).get_data("type") else: format = 0 if self.fsoptionsDict.has_key("migraterb"): migraterb = self.fsoptionsDict["migraterb"] else: migraterb = None if migraterb: migrate = migraterb.get_active() if migrate: fsystem = self.fsoptionsDict[ "migfstypeMenu"].get_active().get_data("type") else: migrate = 0 # set back if we are not formatting or migrating origfstype = logrequest.origfstype if not format and not migrate: fsystem = origfstype mntpt = string.strip(mountCombo.entry.get_text()) if not logrequest or not logrequest.getPreExisting(): # check size specification badsize = 0 try: size = long(sizeEntry.get_text()) except: badsize = 1 if badsize or size <= 0: self.intf.messageWindow( _("Illegal size"), _("The requested size as entered is " "not a valid number greater " "than 0."), custom_icon="error") continue else: size = logrequest.size # is this an existing logical volume or one we're editting if logrequest: preexist = logrequest.getPreExisting() else: preexist = 0 # test mount point # check in pending logical volume requests # these may not have been put in master list of requests # yet if we have not hit 'OK' for the volume group creation if fsystem.isMountable(): used = 0 if logrequest: curmntpt = logrequest.mountpoint else: curmntpt = None for lv in self.logvolreqs: if curmntpt and lv.mountpoint == curmntpt: continue if lv.mountpoint == mntpt: used = 1 break if used: self.intf.messageWindow(_("Mount point in use"), _("The mount point \"%s\" is in " "use, please pick another.") % (mntpt, ), custom_icon="error") continue # check out logical volumne name lvname = string.strip(lvnameEntry.get_text()) if not logrequest or not logrequest.getPreExisting(): err = sanityCheckLogicalVolumeName(lvname) if err: self.intf.messageWindow(_("Illegal Logical Volume Name"), err, custom_icon="error") continue # is it in use? used = 0 if logrequest: origlvname = logrequest.logicalVolumeName else: origlvname = None for lv in self.logvolreqs: if origlvname and lv.logicalVolumeName == origlvname: continue if lv.logicalVolumeName == lvname: used = 1 break if used: self.intf.messageWindow(_("Illegal logical volume name"), _("The logical volume name \"%s\" is " "already in use. Please pick " "another.") % (lvname, ), custom_icon="error") continue # create potential request request = copy.copy(logrequest) pesize = self.peOptionMenu.get_active().get_data("value") size = lvm.clampLVSizeRequest(size, pesize, roundup=1) # do some final tests maxlv = lvm.getMaxLVSize(pesize) if size > maxlv: self.intf.messageWindow(_("Not enough space"), _("The current requested size " "(%10.2f MB) is larger than maximum " "logical volume size (%10.2f MB). " "To increase this limit you can " "increase the Physical Extent size " "for this Volume Group."), custom_icon="error") continue request.fstype = fsystem if request.fstype.isMountable(): request.mountpoint = mntpt else: request.mountpoint = None request.preexist = preexist request.logicalVolumeName = lvname request.size = size request.format = format request.migrate = migrate request.badblock = None # this is needed to clear out any cached info about the device # only a workaround - need to change way this is handled in # partRequest.py really. request.dev = None # make list of original logvol requests so we can skip them # in tests below. We check for mount point name conflicts # above within the current volume group, so it is not # necessary to do now. err = request.sanityCheckRequest(self.partitions, skipMntPtExistCheck=1) if err is None: skiplist = [] for lv in self.origvolreqs: skiplist.append(lv.uniqueID) err = request.isMountPointInUse(self.partitions, requestSkipList=skiplist) if err: self.intf.messageWindow(_("Error With Request"), "%s" % (err), custom_icon="error") continue if (not request.format and request.mountpoint and request.formatByDefault()): if not queryNoFormatPreExisting(self.intf): continue # see if there is room for request (availSpaceMB, neededSpaceMB, fspace) = self.computeSpaceValues(usepe=pesize) tmplogreqs = [] for l in self.logvolreqs: if origlvname and l.logicalVolumeName == origlvname: continue tmplogreqs.append(l) tmplogreqs.append(request) neededSpaceMB = self.computeLVSpaceNeeded(tmplogreqs) if neededSpaceMB > availSpaceMB: self.intf.messageWindow( _("Not enough space"), _("The logical volumes you have " "configured require %g MB, but the " "volume group only has %g MB. Please " "either make the volume group larger " "or make the logical volume(s) smaller.") % (neededSpaceMB, availSpaceMB), custom_icon="error") del tmplogreqs continue # everything ok break # now remove the previous request, insert request created above if not isNew: self.logvolreqs.remove(logrequest) iter = self.getCurrentLogicalVolume() self.logvolstore.remove(iter) self.logvolreqs.append(request) iter = self.logvolstore.append() self.logvolstore.set_value(iter, 0, lvname) if request.fstype and request.fstype.isMountable(): self.logvolstore.set_value(iter, 1, mntpt) else: self.logvolstore.set_value(iter, 1, "N/A") self.logvolstore.set_value(iter, 2, "%g" % (size, )) self.updateVGSpaceLabels() dialog.destroy()
def editLogicalVolume(self, logrequest, isNew = 0): if isNew: tstr = _("Make Logical Volume") else: try: tstr = _("Edit Logical Volume: %s") % (logrequest.logicalVolumeName,) except: tstr = _("Edit Logical Volume") dialog = gtk.Dialog(tstr, self.parent) gui.addFrame(dialog) dialog.add_button('gtk-cancel', 2) dialog.add_button('gtk-ok', 1) dialog.set_position(gtk.WIN_POS_CENTER) maintable = gtk.Table() maintable.set_row_spacings(5) maintable.set_col_spacings(5) row = 0 lbl = createAlignedLabel(_("_Mount Point:")) maintable.attach(lbl, 0, 1, row,row+1) mountCombo = createMountPointCombo(logrequest, excludeMountPoints=["/boot"]) lbl.set_mnemonic_widget(mountCombo) maintable.attach(mountCombo, 1, 2, row, row + 1) row += 1 if not logrequest or not logrequest.getPreExisting(): lbl = createAlignedLabel(_("_File System Type:")) maintable.attach(lbl, 0, 1, row, row + 1) newfstypeCombo = createFSTypeMenu(logrequest.fstype, fstypechangeCB, mountCombo, ignorefs = ["software RAID", "physical volume (LVM)", "vfat", "PPC PReP Boot", "Apple Bootstrap"]) lbl.set_mnemonic_widget(newfstypeCombo) maintable.attach(newfstypeCombo, 1, 2, row, row + 1) row += 1 else: maintable.attach(createAlignedLabel(_("Original File System Type:")), 0, 1, row, row + 1) if logrequest.origfstype and logrequest.origfstype.getName(): newfstypeCombo = gtk.Label(logrequest.origfstype.getName()) else: newfstypeCombo = gtk.Label(_("Unknown")) maintable.attach(newfstypeCombo, 1, 2, row, row + 1) row += 1 if logrequest.fslabel: maintable.attach(createAlignedLabel(_("Original File System " "Label:")), 0, 1, row, row + 1) maintable.attach(gtk.Label(logrequest.fslabel), 1, 2, row, row + 1) row += 1 if not logrequest or not logrequest.getPreExisting(): lbl = createAlignedLabel(_("_Logical Volume Name:")) lvnameEntry = gtk.Entry(32) lbl.set_mnemonic_widget(lvnameEntry) if logrequest and logrequest.logicalVolumeName: lvnameEntry.set_text(logrequest.logicalVolumeName) else: lvnameEntry.set_text(lvm.createSuggestedLVName(self.logvolreqs)) else: lbl = createAlignedLabel(_("Logical Volume Name:")) lvnameEntry = gtk.Label(logrequest.logicalVolumeName) maintable.attach(lbl, 0, 1, row, row + 1) maintable.attach(lvnameEntry, 1, 2, row, row + 1) row += 1 if not logrequest or not logrequest.getPreExisting(): lbl = createAlignedLabel(_("_Size (MB):")) sizeEntry = gtk.Entry(16) lbl.set_mnemonic_widget(sizeEntry) if logrequest: pesize = int(self.peCombo.get_active_value()) sizeEntry.set_text("%Ld" % (logrequest.getActualSize(self.partitions, self.diskset, pesize=pesize),)) else: lbl = createAlignedLabel(_("Size (MB):")) sizeEntry = gtk.Label(str(logrequest.size)) maintable.attach(lbl, 0, 1, row, row+1) maintable.attach(sizeEntry, 1, 2, row, row + 1) row += 1 if not logrequest or not logrequest.getPreExisting(): pesize = int(self.peCombo.get_active_value()) (tspace, uspace, fspace) = self.computeSpaceValues(usepe=pesize) maxlv = min(lvm.getMaxLVSize(pesize), fspace) # add in size of current logical volume if it has a size if logrequest and not isNew: maxlv = maxlv + logrequest.getActualSize(self.partitions, self.diskset, pesize=pesize) maxlabel = createAlignedLabel(_("(Max size is %s MB)") % (maxlv,)) maintable.attach(maxlabel, 1, 2, row, row + 1) self.fsoptionsDict = {} if logrequest.getPreExisting(): (row, self.fsoptionsDict) = createPreExistFSOptionSection(logrequest, maintable, row, mountCombo, showbadblocks=0, ignorefs = ["software RAID", "physical volume (LVM)", "vfat"]) # checkbutton for encryption using dm-crypt/LUKS if not logrequest.getPreExisting(): self.lukscb = gtk.CheckButton(_("_Encrypt")) if logrequest.format or logrequest.type == REQUEST_NEW: self.lukscb.set_data("formatstate", 1) else: self.lukscb.set_data("formatstate", 0) if logrequest.encryption: self.lukscb.set_active(1) else: self.lukscb.set_active(0) maintable.attach(self.lukscb, 0, 2, row, row + 1) row = row + 1 else: self.lukscb = self.fsoptionsDict.get("lukscb") dialog.vbox.pack_start(maintable) dialog.show_all() while 1: rc = dialog.run() if rc == 2: dialog.destroy() return if not logrequest or not logrequest.getPreExisting(): fsystem = newfstypeCombo.get_active_value() format = 1 migrate = 0 else: if self.fsoptionsDict.has_key("formatrb"): formatrb = self.fsoptionsDict["formatrb"] else: formatrb = None if formatrb: format = formatrb.get_active() if format: fsystem = self.fsoptionsDict["fstypeCombo"].get_active_value() else: format = 0 if self.fsoptionsDict.has_key("migraterb"): migraterb = self.fsoptionsDict["migraterb"] else: migraterb = None if migraterb: migrate = migraterb.get_active() if migrate: fsystem = self.fsoptionsDict["migfstypeCombo"].get_active_value() else: migrate = 0 # set back if we are not formatting or migrating origfstype = logrequest.origfstype if not format and not migrate: fsystem = origfstype mntpt = string.strip(mountCombo.get_children()[0].get_text()) if not logrequest or not logrequest.getPreExisting(): # check size specification badsize = 0 try: size = long(sizeEntry.get_text()) except: badsize = 1 if badsize or size <= 0: self.intf.messageWindow(_("Illegal size"), _("The requested size as entered is " "not a valid number greater " "than 0."), custom_icon="error") continue else: size = logrequest.size # is this an existing logical volume or one we're editting if logrequest: preexist = logrequest.getPreExisting() else: preexist = 0 # test mount point # check in pending logical volume requests # these may not have been put in master list of requests # yet if we have not hit 'OK' for the volume group creation if fsystem.isMountable(): used = 0 if logrequest: curmntpt = logrequest.mountpoint else: curmntpt = None for lv in self.logvolreqs: if curmntpt and lv.mountpoint == curmntpt: continue if lv.mountpoint == mntpt: used = 1 break if used: self.intf.messageWindow(_("Mount point in use"), _("The mount point \"%s\" is in " "use, please pick another.") % (mntpt,), custom_icon="error") continue # check out logical volumne name lvname = string.strip(lvnameEntry.get_text()) if not logrequest or not logrequest.getPreExisting(): err = sanityCheckLogicalVolumeName(lvname) if err: self.intf.messageWindow(_("Illegal Logical Volume Name"),err, custom_icon="error") continue # is it in use? used = 0 if logrequest: origlvname = logrequest.logicalVolumeName else: origlvname = None for lv in self.logvolreqs: if origlvname and lv.logicalVolumeName == origlvname: continue if lv.logicalVolumeName == lvname: used = 1 break if used: self.intf.messageWindow(_("Illegal logical volume name"), _("The logical volume name \"%s\" is " "already in use. Please pick " "another.") % (lvname,), custom_icon="error") continue # create potential request request = copy.copy(logrequest) request.encryption = copy.deepcopy(logrequest.encryption) pesize = int(self.peCombo.get_active_value()) size = lvm.clampLVSizeRequest(size, pesize, roundup=1) # do some final tests maxlv = lvm.getMaxLVSize(pesize) if size > maxlv: self.intf.messageWindow(_("Not enough space"), _("The current requested size " "(%10.2f MB) is larger than maximum " "logical volume size (%10.2f MB). " "To increase this limit you can " "create more Physical Volumes from " "unpartitioned disk space and " "add them to this Volume Group.") %(size, maxlv), custom_icon="error") continue request.fstype = fsystem if request.fstype.isMountable(): request.mountpoint = mntpt else: request.mountpoint = None request.preexist = preexist request.logicalVolumeName = lvname request.size = size request.format = format request.migrate = migrate request.badblock = None request.grow = 0 # this is needed to clear out any cached info about the device # only a workaround - need to change way this is handled in # partRequest.py really. request.dev = None if self.lukscb and self.lukscb.get_active(): if not request.encryption: request.encryption = LUKSDevice(passphrase=self.partitions.encryptionPassphrase, format=1) else: request.encryption = None # make list of original logvol requests so we can skip them # in tests below. We check for mount point name conflicts # above within the current volume group, so it is not # necessary to do now. err = request.sanityCheckRequest(self.partitions, skipMntPtExistCheck=1, pesize=pesize) if err is None: skiplist = [] for lv in self.origvolreqs: skiplist.append(lv.uniqueID) err = request.isMountPointInUse(self.partitions, requestSkipList=skiplist) if err: self.intf.messageWindow(_("Error With Request"), "%s" % (err), custom_icon="error") continue if (not request.format and request.mountpoint and request.formatByDefault()): if not queryNoFormatPreExisting(self.intf): continue # see if there is room for request (availSpaceMB, neededSpaceMB, fspace) = self.computeSpaceValues(usepe=pesize) tmplogreqs = [] for l in self.logvolreqs: if origlvname and l.logicalVolumeName == origlvname: continue tmplogreqs.append(l) tmplogreqs.append(request) neededSpaceMB = self.computeLVSpaceNeeded(tmplogreqs, pesize) if neededSpaceMB > availSpaceMB: self.intf.messageWindow(_("Not enough space"), _("The logical volumes you have " "configured require %g MB, but the " "volume group only has %g MB. Please " "either make the volume group larger " "or make the logical volume(s) smaller.") % (neededSpaceMB, availSpaceMB), custom_icon="error") del tmplogreqs continue # everything ok break # now remove the previous request, insert request created above if not isNew: self.logvolreqs.remove(logrequest) iter = self.getCurrentLogicalVolume() self.logvolstore.remove(iter) self.logvolreqs.append(request) iter = self.logvolstore.append() self.logvolstore.set_value(iter, 0, lvname) if request.fstype and request.fstype.isMountable(): self.logvolstore.set_value(iter, 1, mntpt) else: self.logvolstore.set_value(iter, 1, "N/A") self.logvolstore.set_value(iter, 2, "%Ld" % (size,)) self.updateVGSpaceLabels() dialog.destroy()
def peChangeCB(self, widget, peOption): """ handle changes in the Physical Extent option menu widget - menu item which was activated peOption - the Option menu containing the items. The data value for "lastval" is the previous PE value. """ curval = widget.get_data("value") lastval = peOption.get_data("lastpe") lastidx = peOption.get_data("lastidx") # see if PE is too large compared to smallest PV # remember PE is in KB, PV size is in MB maxpvsize = self.getSmallestPVSize() if curval > maxpvsize * 1024: self.intf.messageWindow( _("Not enough space"), _("The physical extent size cannot be " "changed because the value selected " "(%10.2f MB) is larger than the smallest " "physical volume (%10.2f MB) in the " "volume group.") % (curval / 1024.0, maxpvsize), custom_icon="error") peOption.set_history(lastidx) return 0 # see if new PE will make any PV useless due to overhead if lvm.clampPVSize(maxpvsize, curval) * 1024 < curval: self.intf.messageWindow(_("Not enough space"), _("The physical extent size cannot be " "changed because the value selected " "(%10.2f MB) is too large compared " "to the size of the " "smallest physical volume " "(%10.2f MB) in the " "volume group.") % (curval / 1024.0, maxpvsize), custom_icon="error") peOption.set_history(lastidx) return 0 if self.getPVWastedRatio(curval) > 0.10: rc = self.intf.messageWindow( _("Too small"), _("This change in the value of the " "physical extent will waste " "substantial space on one or more " "of the physical volumes in the " "volume group."), type="custom", custom_icon="error", custom_buttons=["gtk-cancel", _("C_ontinue")]) if not rc: peOption.set_history(lastidx) return 0 # now see if we need to fixup effect PV and LV sizes based on PE if curval > lastval: rc = self.reclampLV(curval) if not rc: peOption.set_history(lastidx) return 0 else: self.updateLogVolStore() else: maxlv = lvm.getMaxLVSize(curval) for lv in self.logvolreqs: lvsize = lv.getActualSize(self.partitions, self.diskset) if lvsize > maxlv: self.intf.messageWindow(_("Not enough space"), _("The physical extent size " "cannot be changed because the " "resulting maximum logical " "volume size (%10.2f MB) is " "smaller " "than one or more of the " "currently defined logical " "volumes.") % (maxlv, ), custom_icon="error") peOption.set_history(lastidx) return 0 peOption.set_data("lastpe", curval) peOption.set_data("lastidx", peOption.get_history()) self.updateAllowedLvmPartitionsList(self.availlvmparts, self.partitions, self.lvmlist) self.updateVGSpaceLabels()
def peChangeCB(self, widget, *args): """ handle changes in the Physical Extent option menu widget - menu item which was activated peOption - the Option menu containing the items. The data value for "lastval" is the previous PE value. """ curval = int(widget.get_active_value()) lastval = widget.get_data("lastpe") lastidx = widget.get_data("lastidx") # see if PE is too large compared to smallest PV # remember PE is in KB, PV size is in MB maxpvsize = self.getSmallestPVSize() if curval > maxpvsize * 1024: self.intf.messageWindow(_("Not enough space"), _("The physical extent size cannot be " "changed because the value selected " "(%10.2f MB) is larger than the smallest " "physical volume (%10.2f MB) in the " "volume group.") % (curval/1024.0, maxpvsize), custom_icon="error") widget.set_active(lastidx) return 0 # see if new PE will make any PV useless due to overhead if lvm.clampPVSize(maxpvsize, curval) * 1024 < curval: self.intf.messageWindow(_("Not enough space"), _("The physical extent size cannot be " "changed because the value selected " "(%10.2f MB) is too large compared " "to the size of the " "smallest physical volume " "(%10.2f MB) in the " "volume group.") % (curval/1024.0, maxpvsize), custom_icon="error") widget.set_active(lastidx) return 0 if self.getPVWastedRatio(curval) > 0.10: rc = self.intf.messageWindow(_("Too small"), _("This change in the value of the " "physical extent will waste " "substantial space on one or more " "of the physical volumes in the " "volume group."), type="custom", custom_icon="error", custom_buttons=["gtk-cancel", _("C_ontinue")]) if not rc: widget.set_active(lastidx) return 0 # now see if we need to fixup effect PV and LV sizes based on PE if curval > lastval: rc = self.reclampLV(lastval, curval) if not rc: widget.set_active(lastidx) return 0 else: self.updateLogVolStore() else: maxlv = lvm.getMaxLVSize(curval) for lv in self.logvolreqs: lvsize = lv.getActualSize(self.partitions, self.diskset, pesize=lastval) if lvsize > maxlv: self.intf.messageWindow(_("Not enough space"), _("The physical extent size " "cannot be changed because the " "resulting maximum logical " "volume size (%10.2f MB) is " "smaller " "than one or more of the " "currently defined logical " "volumes.") % (maxlv,), custom_icon="error") widget.set_active(lastidx) return 0 widget.set_data("lastpe", curval) widget.set_data("lastidx", widget.get_active()) self.updateAllowedLvmPartitionsList(self.availlvmparts, self.partitions, self.lvmlist) self.updateVGSpaceLabels()