def tidyAction(): # XXX Using iptables isn't the recommended way to do this, but it works. # We need to make sure the firewall is down to let any necessary network # traffic through, like nfs umount stuff. args = ["/etc/init.d/iptables", "stop"] if os.path.exists(os.path.join(HOST_ROOT, args[0].lstrip('/'))): util.execWithLog(args[0], args, root=HOST_ROOT)
def _mergeNewUsers(oldFile, newFile): for userData in newFile: if not oldFile.hasName(userData.name): args = [ "/usr/sbin/useradd", "-o", # XXX ignore duplicate uids, see bug 278064 "-c", userData.gecos, "-d", userData.dir, "-g", userData.gid, "-s", userData.shell, "-u", userData.uid, userData.name ] try: execWithLog(args[0], args, root=HOST_ROOT, raiseException=True) except Exception, e: raise InstallationError( "Could not add user, '%s', from old installation." % userData.name, e)
def formatDevice(self, devicePath=None, progress=None): args = [ "/usr/sbin/mkswap", "-v1", devicePath ] try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError( "Could not format a linux swap partition.", e)
def formatDevice(self, devicePath=None, progress=None): args = ["/usr/sbin/mkswap", "-v1", devicePath] try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError("Could not format a linux swap partition.", e)
def formatDevice(self, entry=None, progress=None, chroot='/'): raise RuntimeError, "Fat filesystem creation unimplemented." devicePath = "/tmp/foobar" args = ["/sbin/mkdosfs", devicePath] try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError("Could not format a DOS partition", e)
def formatDevice(self, entry=None, progress=None, chroot='/'): raise RuntimeError, "Fat filesystem creation unimplemented." devicePath = "/tmp/foobar" args = ["/sbin/mkdosfs", devicePath] try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError( "Could not format a DOS partition", e)
def formatDevice(self, devicePath=None, progress=None): assert self.volumeName args = ["/usr/sbin/vmkfstools", "-C", self.name, "-b", "%dm" % self.blockSizeMB, "-S", self.volumeName, devicePath] args.extend(self.extraFormatArgs) try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError("Could not format a vmfs volume.", e)
def formatDevice(self, devicePath="", progress=None, chroot='/'): args = ["/usr/sbin/mkfs.ext2"] if self.label: args += ["-L", self.label] args += [devicePath] args.extend(self.extraFormatArgs) try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError("Could not format a linux partition.", e)
def write(self): args = ["/usr/sbin/esxcfg-auth", "--kickstart", "--nostart"] # Set the required password complexity (see bug 359840) # XXX Need to keep in sync with visor parameters held here: # bora/install/vmvisor/environ/etc/pam.d/common-password args += ["--usepamqc", "8", "8", "8", "7", "6", "0"] args += self.getArgList() try: execWithLog(args[0], args, root=HOST_ROOT, raiseException=True) except Exception, e: raise InstallationError("Could not set authentication method.", e)
def formatDevice(self, devicePath=None, progress=None): assert self.volumeName args = [ "/usr/sbin/vmkfstools", "-C", self.name, "-b", "%dm" % self.blockSizeMB, "-S", self.volumeName, devicePath ] args.extend(self.extraFormatArgs) try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError("Could not format a vmfs volume.", e)
def unmount(self): if self.mountedServer: # Use the nfs specific umount, since the busybox one does not work # well with unreachable nfs servers. nfsMountPoint = self.mountpoint if self.mountedRoot.endswith('.iso'): util.umount(self.mountpoint) nfsMountPoint = "%s-isosrc" % self.mountpoint command = '/sbin/umount.nfs' argv = [command, nfsMountPoint, '-f'] execWithLog(command, argv, level=logging.DEBUG) self.mountedServer = None self.mountedRoot = None
def removeVmdkFile(vmdkPath): if os.path.exists(vmdkPath): # remove the vmdk file with vmkfstools first and then attempt # to remove the directory args = [ "/usr/sbin/vmkfstools", "-U", vmdkPath ] try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError("Could not delete old COS vmdk.", e) log.debug("Removing %s" % vmdkPath) shutil.rmtree(os.path.dirname(vmdkPath))
def removeVmdkFile(vmdkPath): if os.path.exists(vmdkPath): # remove the vmdk file with vmkfstools first and then attempt # to remove the directory args = ["/usr/sbin/vmkfstools", "-U", vmdkPath] try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError("Could not delete old COS vmdk.", e) log.debug("Removing %s" % vmdkPath) shutil.rmtree(os.path.dirname(vmdkPath))
def write(self): args = [ "/usr/sbin/esxcfg-auth", "--kickstart", "--nostart" ] # Set the required password complexity (see bug 359840) # XXX Need to keep in sync with visor parameters held here: # bora/install/vmvisor/environ/etc/pam.d/common-password args += [ "--usepamqc", "8", "8", "8", "7", "6", "0" ] args += self.getArgList() try: execWithLog(args[0], args, root=HOST_ROOT, raiseException=True) except Exception, e: raise InstallationError( "Could not set authentication method.", e)
def formatDevice(self, devicePath="", progress=None, chroot='/'): extFileSystem.formatDevice(self, devicePath, progress, chroot) # XXX - crufty hack for ext3 os.system('touch /etc/mtab') # XXX - add back -Odir_index when htree is safe args = ["/usr/sbin/tune2fs", "-c0", "-i0", "-j", devicePath] try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError( "Could not enable journalling on a linux partition.", e)
def _normalizeUsers(oldFile): '''Performs extra migrations steps for users. Ensures that non-pseudo-users have a home directory under /home and their shell is sane.''' for userData in oldFile: log.debug("migrating user -- %s" % userData.name) if userData.shell == "/sbin/nologin": # XXX remove me? log.debug(" not normalizing pseudo-user") continue newHomeDir = os.path.join(HOST_ROOT, userData.dir.lstrip('/')) oldHomeDir = os.path.join(ESX3_INSTALLATION, userData.dir.lstrip('/')) if os.path.exists(newHomeDir): log.debug(" user dir already exists in new install, skipping...") continue if not os.path.exists(os.path.join(HOST_ROOT, oldHomeDir.lstrip('/'))): log.debug(" user dir does not exist in old install, skipping...") continue expectedDir = "/home/%s" % userData.name if userData.dir != expectedDir: log.warn("changing home directory path for %s to %s" % ( userData.name, expectedDir)) userData.dir = expectedDir newHomeDir = os.path.join(HOST_ROOT, expectedDir.lstrip('/')) args = ["/usr/sbin/usermod", "-d", expectedDir, userData.name] execWithLog(args[0], args, root=HOST_ROOT, raiseException=True) shellPath = os.path.join(HOST_ROOT, userData.shell.lstrip('/')) if not os.path.exists(shellPath): oldShell = userData.shell userData.shell = "/bin/bash" log.warn("unknown user shell, %s, switching to %s" % ( oldShell, userData.shell)) args = ["/usr/sbin/usermod", "-s", userData.shell, userData.name] try: execWithLog(args[0], args, root=HOST_ROOT, raiseException=True) except Exception, e: raise InstallationError("Could not change user shell.", e) _copyTreeForUser(os.path.join(HOST_ROOT, "etc/skel"), HOST_ROOT + userData.dir, int(userData.uid), int(userData.gid)) os.symlink(oldHomeDir, os.path.join(newHomeDir, "esx3-home"))
def _normalizeUsers(oldFile): '''Performs extra migrations steps for users. Ensures that non-pseudo-users have a home directory under /home and their shell is sane.''' for userData in oldFile: log.debug("migrating user -- %s" % userData.name) if userData.shell == "/sbin/nologin": # XXX remove me? log.debug(" not normalizing pseudo-user") continue newHomeDir = os.path.join(HOST_ROOT, userData.dir.lstrip('/')) oldHomeDir = os.path.join(ESX3_INSTALLATION, userData.dir.lstrip('/')) if os.path.exists(newHomeDir): log.debug(" user dir already exists in new install, skipping...") continue if not os.path.exists(os.path.join(HOST_ROOT, oldHomeDir.lstrip('/'))): log.debug(" user dir does not exist in old install, skipping...") continue expectedDir = "/home/%s" % userData.name if userData.dir != expectedDir: log.warn("changing home directory path for %s to %s" % (userData.name, expectedDir)) userData.dir = expectedDir newHomeDir = os.path.join(HOST_ROOT, expectedDir.lstrip('/')) args = ["/usr/sbin/usermod", "-d", expectedDir, userData.name] execWithLog(args[0], args, root=HOST_ROOT, raiseException=True) shellPath = os.path.join(HOST_ROOT, userData.shell.lstrip('/')) if not os.path.exists(shellPath): oldShell = userData.shell userData.shell = "/bin/bash" log.warn("unknown user shell, %s, switching to %s" % (oldShell, userData.shell)) args = ["/usr/sbin/usermod", "-s", userData.shell, userData.name] try: execWithLog(args[0], args, root=HOST_ROOT, raiseException=True) except Exception, e: raise InstallationError("Could not change user shell.", e) _copyTreeForUser(os.path.join(HOST_ROOT, "etc/skel"), HOST_ROOT + userData.dir, int(userData.uid), int(userData.gid)) os.symlink(oldHomeDir, os.path.join(newHomeDir, "esx3-home"))
def umountEject(uMountPoint): """Attempt to reliably unmount the media and eject it. This can be kludgey. umount on some systems doesn't free up the resource that eject thinks has to be free. """ # TODO AND NOTES: # 1. Deliberately inserting the wrong CD can lead to duplicate mounts, # and later umount trouble. Workaround: select a separate console, # and manually umount. Need to bullet-proof this better. # 2. umount immediately followed by eject has been known to failed # on certain other Busybox/uClibc/2.4kernel systems. Injecting a sleep # works around the problem. import time for trial in (1, 2, 3): if uMountPoint: # guard against NoneType, '' status = util.umount(uMountPoint) if status == 0: # success break else: args = ["/usr/bin/umount", "-f", uMountPoint] status = util.execWithLog(args[0], args) log.warn('Forced umount of %s: %d' % (uMountPoint, status)) time.sleep(1) log.warn('customdrivers_ui umount attempt %d failed' % trial) status = cdutil.ejectCdrom() return status
def mount(self, host, root, options="nolock"): self._checkNFSAvailable() self.unmount() nfsMountPoint = self.mountpoint nfsRoot = root isoName = None if root.endswith('.iso'): nfsRoot, isoName = os.path.split(root) nfsMountPoint = "%s-isosrc" % self.mountpoint if not os.path.exists(nfsMountPoint): os.makedirs(nfsMountPoint) command = '/sbin/mount.nfs' argv = [ command, '%s:%s' % (host, nfsRoot), nfsMountPoint, '-v', '-o', options ] rc = execWithLog(command, argv) if rc == 0: self.mountedServer = host self.mountedRoot = root if isoName: if util.mount(os.path.join(nfsMountPoint, isoName), self.mountpoint, loopMount=True, fsTypeName='iso9660') != 0: self.unmount() return False return True else: return False
def mount(self, host, root, options="nolock"): self._checkNFSAvailable() self.unmount() nfsMountPoint = self.mountpoint nfsRoot = root isoName = None if root.endswith('.iso'): nfsRoot, isoName = os.path.split(root) nfsMountPoint = "%s-isosrc" % self.mountpoint if not os.path.exists(nfsMountPoint): os.makedirs(nfsMountPoint) command = '/sbin/mount.nfs' argv = [command, '%s:%s' % (host, nfsRoot), nfsMountPoint, '-v', '-o', options] rc = execWithLog(command, argv) if rc == 0: self.mountedServer = host self.mountedRoot = root if isoName: if util.mount(os.path.join(nfsMountPoint, isoName), self.mountpoint, loopMount=True, fsTypeName='iso9660') != 0: self.unmount() return False return True else: return False
def run(self, chroot="/"): path = "tmp/ks-script" openPath = os.path.join(chroot, path) if self.inChroot: execPath = os.path.join('/', path) else: execPath = openPath f = open(openPath, "w") f.write(self.script) f.close() os.chmod(openPath, 0700) cmd = [self.interp, execPath] if self.inChroot: execRoot = chroot else: execRoot = '/' try: rc = util.execWithLog(cmd[0], cmd, level=LOGLEVEL_HUMAN, root=execRoot, timeoutInSecs=self.timeoutInSecs, raiseException=(not self.ignoreFailure)) except Exception, e: raise InstallationError("User-supplied script failed.", e)
def rebuildRpmDb(): instRoot = '/mnt/sysimage' for path in glob.glob(os.path.join(instRoot, "var/lib/rpm/__db.0*")): os.remove(path) args = ["/bin/rpm", "--rebuilddb"] status = util.execWithLog(args[0], args, root=instRoot) assert status == 0
def create(self): assert self.vmfsVolume path = os.path.join("/vmfs/volumes", self.vmfsVolume, self.imagePath) fullPath = os.path.normpath(os.path.join(path, self.imageName)) # remove any existing vmdk file first removeVmdkFile(fullPath) if not os.path.exists(path): os.makedirs(path) args = ["/usr/sbin/vmkfstools", "-c", "%dM" % (self.size, ), fullPath] try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError("Could not create new COS vmdk.", e)
def checkSerialNumber(value): args = ["/usr/sbin/check_serial", "-c", value] rc = util.execWithLog(args[0], args) if rc != 0: if os.WIFEXITED(rc): code = os.WEXITSTATUS(rc) else: code = None msg = LICENSE_CHECK_RESULT.get( code, "Internal error while validating serial number.") raise LicenseException(msg)
def create(self): assert self.vmfsVolume path = os.path.join("/vmfs/volumes", self.vmfsVolume, self.imagePath) fullPath = os.path.normpath(os.path.join(path, self.imageName)) # remove any existing vmdk file first removeVmdkFile(fullPath) if not os.path.exists(path): os.makedirs(path) args = [ "/usr/sbin/vmkfstools", "-c", "%dM" % (self.size,), fullPath ] try: util.execWithLog(args[0], args, raiseException=True) except Exception, e: raise InstallationError("Could not create new COS vmdk.", e)
def migrateActionXinetdConf(oldPath, _newPath, accum): if not os.path.isfile(oldPath): log.info("skipping non-file -- %s" % oldPath) return if os.path.splitext(oldPath)[1] in \ [".rpmnew", ".rpmsave", ".rpmorig", ".swp"]: log.info("skipping file with bad extension -- %s" % oldPath) return log.info("updating services in %s" % oldPath) xc = XinetdConf() conf = open(oldPath) try: for line in conf: xc.feedLine(line) for directory in xc.includedDirs: globbed = os.path.join(directory, "*") handlers.MIGRATION_HANDLERS[globbed] = migrateActionXinetdConf accum.append(globbed) for filename in xc.includedFiles: handlers.MIGRATION_HANDLERS[filename] = migrateActionXinetdConf accum.append(filename) for serviceName, serviceSettings in xc.services.items(): xinetPath = os.path.join(HOST_ROOT, "etc/xinetd.d", serviceName) if not os.path.exists(xinetPath): log.info(" skipping discontinued xinetd service -- %s\n" % serviceName) continue disable = serviceSettings.get('disable', 'yes').lower() if disable in ('yes', '1', 'true'): onoff = 'off' else: onoff = 'on' args = [ "/sbin/chkconfig", serviceName, onoff, ] rc = util.execWithLog(args[0], args, root=HOST_ROOT) # assert rc == 0 # TODO: handle errors finally: conf.close() return False
def runtimeAction(self): # TODO: Figure out loadkeys, anaconda had a special one half written # in python that is different from the standard one. # args = ["/usr/bin/loadkeys", self.keytable] # rc = util.execWithLog(args[0], args) # assert rc == 0 # TODO: handle errors args = [ "/usr/bin/setxkbmap", "-layout", self.layout, "-model", self.model ] if self.variant: args.extend(["-variant", self.variant]) if self.options: args.extend(["-option", self.options]) rc = util.execWithLog(args[0], args) if rc != 0: errormsg = 'Cannot set keyboard to layout %s model %s' % \ (self.layout, self.model) log.error(errormsg) raise RuntimeError(errormsg)
def runtimeAction(self): # TODO: Figure out loadkeys, anaconda had a special one half written # in python that is different from the standard one. # args = ["/usr/bin/loadkeys", self.keytable] # rc = util.execWithLog(args[0], args) # assert rc == 0 # TODO: handle errors args = ["/usr/bin/setxkbmap", "-layout", self.layout, "-model", self.model] if self.variant: args.extend(["-variant", self.variant]) if self.options: args.extend(["-option", self.options]) rc = util.execWithLog(args[0], args) if rc != 0: errormsg = 'Cannot set keyboard to layout %s model %s' % \ (self.layout, self.model) log.error(errormsg) raise RuntimeError(errormsg)
if serviceMatch.group(1) == "S": onoff = "on" else: onoff = "off" name = serviceMatch.group(2) initPath = os.path.join(HOST_ROOT, "etc/init.d", name) isChkconfigService = False try: initFile = open(initPath) for line in initFile: if 'chkconfig' in line: isChkconfigService = True break except IOError, _e: log.info(" service discontinued -- %s" % name) return False if not isChkconfigService: log.info(" service is not supported by chkconfig -- %s" % name) return False args = ["/sbin/chkconfig", "--level", level, name, onoff] rc = util.execWithLog(args[0], args, root=HOST_ROOT) # assert rc == 0 # TODO: handle errors return False
if rule['state'] == userchoices.PORT_STATE_OPEN: args += [ "--openPort", "%(number)s,%(protocol)s,%(direction)s,%(name)s" % rule ] else: args += [ "--closePort", "%(number)s,%(protocol)s,%(direction)s" % rule ] # esxcfg-firewall fails if --closePort is used on an already closed port try: util.execWithLog(args[0], args, root=HOST_ROOT, raiseException=True) except util.ExecError, e: if rule['state'] == userchoices.PORT_STATE_OPEN: raise InstallationError( "Could not %(state)s port %(number)s in the firewall." % rule, e) except Exception, e: raise InstallationError( "Could not %(state)s port %(number)s in the firewall." % rule, e) serviceRules = userchoices.getServiceRules() # If we've set the time from an NTP server, we also need to open port 123 isNTP = bool(userchoices.getTimedate().get('ntpServer'))
if os.path.getsize(metadst) == 0: log.warn("The server gave '%s' as an empty file" % metadst) os.unlink(metadst) err = True except Exception, err: # downloadLocally() function doesn't distinguish between not found and # transfer or other error. log.warn('Esxupdate meta-data not present or not retrievable: %s' % err) if scui.tty6Handler: scui.tty6Handler.setLevel(prevLevel) if err: return if not metadst.startswith(consts.HOST_ROOT): # If file was not downloaded to somewhere under HOST_ROOT, move it. try: tmploc = os.path.join(consts.HOST_ROOT, 'tmp', 'metadata.zip') shutil.move(metadst, tmploc) metadst = tmploc except Exception, e: log.warn('Unable to move esxupdate meta-data to host root: %s' % e) return metachroot = os.path.join('/', metadst[len(consts.HOST_ROOT):]) args = ['/usr/sbin/esxupdate', 'syncdb', '-m', metachroot] if util.execWithLog(args[0], args, root=consts.HOST_ROOT): log.warn('Failed to import esxupdate database information.') try: os.unlink(metadst) except Exception, e: log.warn('Failed to remove esxupdate meta-data after import: %s' % e)
def write(self): Password.write(self) # remove checking password validation for root args = ["/usr/bin/chage", "-M", "-1", "root"] execWithLog(args[0], args, root=HOST_ROOT)
name = serviceMatch.group(2) initPath = os.path.join(HOST_ROOT, "etc/init.d", name) isChkconfigService = False try: initFile = open(initPath) for line in initFile: if 'chkconfig' in line: isChkconfigService = True break except IOError, _e: log.info(" service discontinued -- %s" % name) return False if not isChkconfigService: log.info(" service is not supported by chkconfig -- %s" % name) return False args = [ "/sbin/chkconfig", "--level", level, name, onoff ] rc = util.execWithLog(args[0], args, root=HOST_ROOT) # assert rc == 0 # TODO: handle errors return False
raise InstallationError( "Could not change global firewall rules.", e) for rule in userchoices.getPortRules(): args = ["/usr/sbin/esxcfg-firewall"] if rule['state'] == userchoices.PORT_STATE_OPEN: args += ["--openPort", "%(number)s,%(protocol)s,%(direction)s,%(name)s" % rule] else: args += ["--closePort", "%(number)s,%(protocol)s,%(direction)s" % rule] # esxcfg-firewall fails if --closePort is used on an already closed port try: util.execWithLog(args[0], args, root=HOST_ROOT, raiseException=True) except util.ExecError, e: if rule['state'] == userchoices.PORT_STATE_OPEN: raise InstallationError( "Could not %(state)s port %(number)s in the firewall." % rule, e) except Exception, e: raise InstallationError( "Could not %(state)s port %(number)s in the firewall." % rule, e) serviceRules = userchoices.getServiceRules() # If we've set the time from an NTP server, we also need to open port 123 isNTP = bool(userchoices.getTimedate().get('ntpServer')) if isNTP:
metadst = remote_files.downloadLocally(metasrc, clobberCache = True) if os.path.getsize(metadst) == 0: log.warn("The server gave '%s' as an empty file" % metadst) os.unlink(metadst) err = True except Exception, err: # downloadLocally() function doesn't distinguish between not found and # transfer or other error. log.warn('Esxupdate meta-data not present or not retrievable: %s' % err) if scui.tty6Handler: scui.tty6Handler.setLevel(prevLevel) if err: return if not metadst.startswith(consts.HOST_ROOT): # If file was not downloaded to somewhere under HOST_ROOT, move it. try: tmploc = os.path.join(consts.HOST_ROOT, 'tmp', 'metadata.zip') shutil.move(metadst, tmploc) metadst = tmploc except Exception, e: log.warn('Unable to move esxupdate meta-data to host root: %s' % e) return metachroot = os.path.join('/', metadst[len(consts.HOST_ROOT):]) args = ['/usr/sbin/esxupdate', 'syncdb', '-m', metachroot] if util.execWithLog(args[0], args, root=consts.HOST_ROOT): log.warn('Failed to import esxupdate database information.') try: os.unlink(metadst) except Exception, e: log.warn('Failed to remove esxupdate meta-data after import: %s' % e)
def hostAction(_context): cmd = "/sbin/chkconfig" # Turn these guys off for the sake of security. util.execWithLog(cmd, [cmd, "netfs", "off"], root=HOST_ROOT) util.execWithLog(cmd, [cmd, "nfslock", "off"], root=HOST_ROOT) util.execWithLog(cmd, [cmd, "portmap", "off"], root=HOST_ROOT) # our firewall script does what is necessary util.execWithLog(cmd, [cmd, "iptables", "off"], root=HOST_ROOT) # on cos 26 chkconfig --add doesn't turn the service on. util.execWithLog(cmd, [cmd, "sshd", "on"], root=HOST_ROOT) # If we've set the time from an NTP server, we need to start ntpd isNTP = bool(userchoices.getTimedate().get('ntpServer')) if isNTP: util.execWithLog(cmd, [cmd, "ntpd", "on"], root=HOST_ROOT)