def makePath(src, dest, glob=None): """ Format a destination path @param src: component or system path @param dest: destination path @param glob: glob str if there was one, otherwise None @returns: absolute destination path """ src = path(src) dest = path(dest) if not glob or not glob.endswith('*'): if glob and '*' in glob: return dest.joinpath(src.basename()) else: return dest else: strip = glob.replace('*', '', 1) # Remove leading glob. Example: foo/* if strip.endswith('/'): src = src.replace(strip, '', 1) # Otherwise, maintain lead because it's part of the path. # Example: foo* return dest.joinpath(src)
def GetFilePath(self, filePath): """ Extracts a file from the component and returns the temp path """ # Create a temporary file and extract the contents into it namedtempfile = NamedTemporaryFile() self._component.CopyFile(filePath, namedtempfile.name) tempfile = namedtempfile.name + ".bak" path(namedtempfile.name).copy(tempfile) namedtempfile.close() # Return the temp file path return tempfile
def PostInstall(self, old, new, upgrade): # If an arbitrator already exists and it's not a symlink, back # it up and create a symlink to our new ones. This must be # done for co-installs with WS 7.x arb = BINDIR / 'vmware-usbarbitrator' if arb.exists(): if not arb.islink(): # Make the destination directory if it doesn't already exist dest = path(LIBDIR / 'vmware/lib') if not dest.exists(): dest.makedirs() # Backup the program (Don't use a path, explicitly convert to a string) arb.copyfile( str(LIBDIR / 'vmware/lib/vmware-usbarbitrator.old')) arb.remove() else: # Remove the old link arb.remove() # Now that our space in the BINDIR is clear, install the symlink. path(LIBDIR / 'vmware/bin/vmware-usbarbitrator').symlink(str(arb)) inits = self.LoadInclude('initscript') inits.ConfigureService( 'vmware-USBArbitrator', 'This services starts and stops the USB Arbitrator.', 'localfs', # Start 'localfs', # Stop '', '', 50, 8) # Set "SYSTEMCTL_SKIP_REDIRECT" to skip systemctl when doing # start/stop action, such as RHEL 8 which systemctl will bring # trouble for USB Arbitrator service start/stop. os.environ['SYSTEMCTL_SKIP_REDIRECT'] = "1" # Stop the USB Arbitrator init script script = INITSCRIPTDIR / 'vmware-USBArbitrator' if script.exists() and self.RunCommand( script, 'stop', ignoreErrors=True).retCode != 0: log.Warn( 'Unable to stop current USB Arbitrator service. Not fatal.') # Start the USB Arbitrator init script script = INITSCRIPTDIR / 'vmware-USBArbitrator' if script.exists() and self.RunCommand( script, 'start', ignoreErrors=True).retCode != 0: log.Error('Unable to start USB Arbitrator service.') # Unset "SYSTEMCTL_SKIP_REDIRECT". del os.environ['SYSTEMCTL_SKIP_REDIRECT']
def __getattr__(self, attr): """ For attributes that don't exist in this class, pass them through to path. """ func = getattr(path, attr, None) if func and callable(func): return lambda *args, **kwargs: func(path(self._expand()), *args, ** kwargs) elif func: return getattr(path(self._expand()), attr) else: raise AttributeError('type object %s has no attribute %s' % (self.__name__, attr))
def Validate(self, answer): if not isinstance(answer, str): raise ValidationError('File must be a string') # If it's not required accept the given answer as long as it is # empty. if not self._required and not answer.strip(): return '' answer = path(answer.strip()) if not answer: raise ValidationError('File must be non-empty') if not answer.isabs(): raise ValidationError('File is not an absolute path') if not answer.isfile(): raise ValidationError('File path is not a file') if not answer.exists() and self._mustExist: raise ValidationError('File path does not exist') if not answer.access(os.W_OK) and self._writeable and self._mustExist: raise ValidationError('File path is not writeable') return answer
def GetFileValue(self, key): """ Get the value of one of our special files. ie: BINDIR, LIBDIR """ val = path.path(self.MessageOut(self.whoami(), key)) return val
def PreUninstall(self, old, new, upgrade): # Stop the USB Arbitrator init script script = INITSCRIPTDIR / 'vmware-USBArbitrator' # Set "SYSTEMCTL_SKIP_REDIRECT" to skip systemctl when doing # start/stop action, such as RHEL 8 which systemctl will bring # trouble for USB Arbitrator service start/stop. os.environ['SYSTEMCTL_SKIP_REDIRECT'] = "1" if script.exists() and self.RunCommand( script, 'stop', ignoreErrors=True).retCode != 0: log.Warn('Unable to stop USB Arbitrator service.') # Unset "SYSTEMCTL_SKIP_REDIRECT". del os.environ['SYSTEMCTL_SKIP_REDIRECT'] inits = self.LoadInclude('initscript') inits.DeconfigureService('vmware-USBArbitrator') self.pycFile = None if upgrade: # It means that this is installed vmis and will be uninstalled, # the installing Python runtime is version-higher than or equals # to ours, remember the .pyc file location to make sure it will # be removed in the phase PostUninstall. pycFile = getattr(inits, '__cached__', '') if not pycFile: pyFile = getattr(inits, '__file__', '') if pyFile: pycFile = self.CompilePythonFile(pyFile) if pycFile: self.pycFile = path(pycFile)
def __init__(self, component, key, text, required, level=CUSTOM, default='0', proglist=[]): super(ClosePrograms, self).__init__(component, key, text, required, level=level, default=default) self.min = min self.max = max self.type = QUESTION_CLOSEPROGRAMS self.initscript = None # XXX: Workaround # We need to stash this for later use. Explicitly force it to a string, # then create a new path object from it. If we don't, then the # INITSCRIPTDIR object will be evauluated later in the GUI thread, requiring # database access. Since sqlite3 runs in the main installer thread and refuses # to run in more than one thread, it will throw an exception. # # If it's not set to anything, don't store it. if INITSCRIPTDIR: self.initscript = path(str(INITSCRIPTDIR / 'vmware'))
def __init__(self, options): """ @param options: dictionary of custom transaction options """ # Queue isn't a new-style object so super doesn't work. MainLoop.__init__(self) self.count = 0 # Number of discerete steps to be executed self.currentCount = 0 # Number of steps executed self.opts = dict(OPTIONS) # Transaction options self.exitCode = 0 # Default exit code self.success = True # Overall success self.backLimit = 0 # The earliest question to allow a step back to self.installMode = options['installMode'] if 'level' in options: options['level'] = LEVELS[options['level'].upper()] self.opts.update(options) self.temp = path(tempfile.mkdtemp()) signal.signal(signal.SIGINT, self.Abort) # Create the UI instance and set it. self.ui = Wizard(self) ui.instance = self.ui if ui.TYPE == 'gtk': # Now that we know we're using GTK, run initialization. self.ui.InitialSetup()
def RegisterDirectory(self, dirname, mtime=None, fileType='File'): """ Recursively register all files in a directory with the installer. """ dirname = path(dirname) itr = dirname.walk() for filename in itr: if filename.isfile(): # Don't register directories. self.RegisterFile(filename, mtime, fileType)
def CompilePythonFile(self, filePath): """ Byte-compiles a Python file for the current component. This should only be used in PostInstall for files that are dynamically generated and cannot be installed at install time. It's advisable to register this file with Register File if it needs to be removed by the installer during uninstall. """ compiled = path.path(_compilePython(str(filePath))) return compiled
def ExtractComponents(components, extractDir): """ Actual workhorse for bundle extraction. Will take the provided list of components and extract them to the specified directory. @param components: list of either file or directory components @param extractDir: directory to extract components to (if it exists, the directory will be deleted and recreated) """ # The caller has asked to simply extract all the files in each # of the components. No exceptions are caught within this method, # so if any are raised, they will bubble up the call stack. # First, validate the supplied path. If something exists at the # specified path location, error out. extractDir = path(extractDir) if not extractDir.isabs(): extractDir = path(os.getcwd()) / extractDir if extractDir.exists(): raise DirectoryExistsError('Could not extract to %s. Directory' ' already exists.' % extractDir) for c in components: # c.fileset contains the FileEntry objects that we wish to extract. # The CopyFile() method will extract the files for us. for filePath, fileEntry in c.fileset.items(): # Identify the absolute path for the file. filePath = extractDir / c.name / filePath # Create all directories to the file. filePathDir = filePath.dirname() if not filePathDir.exists(): filePathDir.makedirs() # Create the file itself. c.CopyFile(fileEntry, filePath) # Write the manifest manifestFile = extractDir / c.name / 'manifest.xml' manifestFile.write_bytes(c.manifest)
def Install(self, component, dest, precopy=None): if self.IsRelative(): entries = list(component.Glob(str(self))) if '*' in self: glob = self else: glob = None for entry in entries: fileDest = makePath(entry.path, dest, glob) precopy and precopy(fileDest) component.CopyFile(entry, fileDest) fileDest.chmod(dest.perm) yield fileDest else: # Resolve dest to a concrete path (convert any BINDIR or SBINDIR # entries to the actual path.) and copy. path(self).copy2(str(dest)) yield dest
def LocateAppControl(self): """ Attempt to locate an instance of vmware-app-control. This function will search the original LIBDIR first. If not found there, then it will fall back on the installer supplied app control. @returns: A path object to the located App Control or None if not found. """ # Try self.ORIGLIBDIR first loc = path(self.ORIGLIBDIR / 'vmware/bin/vmware-app-control') self.LIBDIR = self.ORIGLIBDIR / 'vmware' if loc.exists(): return loc return None
def __init__(self): # We need to save the original library directory for later use. # We will need to get to programs that were originally installed on the system # and if the user changes LIBDIR, we don't want the new one. Explicitly # cast it to a string and create a new path object with that path. self.ORIGLIBDIR = path(str(LIBDIR)) self.appControl = self.LocateAppControl() if self.appControl: log.info('Initialized UIAppControl. Located at: %s' % self.appControl) else: log.info('Could not locate installer App Control.') raise AppControlNotFoundError( 'Could not locate installer App Control.')
def _lock(self, lockFile): """ Acquire the installer lock if locking is enabled @param lockFile: path to the lock file """ if not self._useLock: return self._lockFileName = path(lockFile) self._lockFileName.touch() log.debug('Created lock file: %s', self._lockFileName) self._lockFile = self._lockFileName.open() fcntl.flock(self._lockFile.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
def Which(program): """ Gets the PATH environment variable and checks for program in order. @param program: Executable to search for @returns: Full path if found and executable, None otherwise """ systemPath = os.environ.get('PATH') paths = systemPath.split(':') for p in paths: fullPath = path(p) / program if fullPath.isexe(): return str(fullPath) # Return a string, not a path object return None
def LoadComponent(cls, source): """ Load the component from the given source directory """ source = path(source) if not source.isdir(): raise ComponentError('%s is not a directory' % source) fileobj = None try: fileobj = open(source.joinpath('manifest.xml'), 'rb') manifest = fileobj.read() except: fileobj and fileobj.close() raise return super(FileSystemComponent, cls).LoadComponent(manifest, source)
def Load(components, bundlePath): """ Load() is a generator function used within the context of a with statement. It will add to repository all the files and directories contained within the specified bundle and components. @param components: list of either file or directory components @param bundlePath: file path to the bundle """ log.debug('Requesting component loading of %s', components) log.debug('Requesting bundle loading from %s', bundlePath) components = components or [] close = [] # File handles to close. loaded = [] # Keep loaded components in here or # they go out of scope and repository # deletes them. try: for filePath in components: filePath = path(filePath) if filePath.isfile(): fobj = open(filePath, 'rb') comp = FileComponent.LoadComponent(fobj) loaded.append(comp) common.repository.Add(comp) elif filePath.isdir(): comp = FileSystemComponent.LoadComponent(filePath) loaded.append(comp) common.repository.Add(comp) else: raise ComponentError('%s is not a component' % filePath) bundle = bundlePath and open(bundlePath, 'rb') if bundle: close.append(bundle) bundle = bundle and Bundle.LoadBundle(bundle) if bundle: for c in bundle.components: common.repository.Add(c) yield finally: for f in close: f.close()
def GetFileText(self, filePath, textMode = True): """ Extracts a file from the component and returns the contents """ # Create a temporary file and extract the contents into it namedtempfile = NamedTemporaryFile() self._component.CopyFile(filePath, namedtempfile.name) # Read in the contents of that file to memory tempfile = path(namedtempfile.name) if textMode: filetxt = tempfile.text() else: filetxt = tempfile.bytes() # Close our temp file, which also deletes it namedtempfile.close() # Return the file contents return filetxt
def Install(self, component, dest, precopy=None): if ComponentOnly() is False: log.debug('Creating symlink from %s to %s', self, dest) if precopy: precopy(dest) dest = path(dest) # @fixme: have to coerce it to a string type # instead of Path Template or isinstance will # fail # Use relative paths during package creation (staging) to avoid # creating the wrong hard-coded paths. This is false by default # but set to True during component creation. if useRelativeSymlinks: dest.dirname().relpathto(self).symlink(dest) else: self.symlink(dest) yield dest
def GetDefault(self): """ Locate init script directory using INITDIR """ # INITDIR must be asked first since this question is based off # the answer for INITDIR. if str(INITDIR): init = INITDIR.abspath() # strip off any weird /'s if not init.endswith('init.d'): init = init / 'init.d' return init else: # Try /etc/init.d as a default. If it doesn't exist, then we give up and use no default. init = path('/etc/init.d') if init.exists(): return init else: log.warning('No init script directory was able to be located') return ''
def Validate(self, answer): """ Validate that the given answer contains the expected directories @raises: ValidationError """ super(InitDir, self).Validate(answer) # Accept a blank entry for those systems that don't have rc?.d style # init directories. if answer == '': return answer rcdirs = ('rc0.d', 'rc1.d', 'rc2.d', 'rc3.d', 'rc4.d', 'rc5.d', 'rc6.d') answer = path(answer) if all([(answer / rc).exists() for rc in rcdirs]): return answer else: raise ValidationError('%s is not an init directory' % answer)
def RegisterFile(self, filename, mtime=None, fileType='File'): """ Register a file with the installer. """ # fileType is always a string. Convert it to a real object # for storage in self._files if not isinstance(fileType, str): raise TypeError('File Type %s was not provided as a string. ' 'Check your component!' % fileType) # Map fileType to a real Type class. ftype = getattr(files, fileType, None) if not ftype: raise ValueError('File Type %s does not exist! ' \ 'Check your component!' % fileType) # We want the integer id of this file type to store in the database ftype = ftype.id # If no mtime was given, grab it now regfile = path(filename) if not mtime: mtime = int(regfile.mtime) db.files.Add(regfile, mtime, ftype, self._component.uid)
def __div__(self, divisor): ret = Destination(path(self.rawText) / divisor) ret.perm = self.perm ret.fileType = self.fileType return ret