def _createFile(self): super(CommandLock, self)._createFile() # For now, we default to permitting shared locks from non-root # processes. The sysadmin may change this; we won't change the # permissions once the file has been created. # # N.B.: The names may not be sanitized for use with a shell! cmd = Command(["chmod", "644", self.path]) cmd.run()
def preflight(self, args): """Perform checks prior to actually executing the command. Arguments: args (dict): The command line arguments (used by subclasses) Raises: OperationError """ if self.requiresRoot and (os.getuid() != 0): msg = _("You must be root to use the \"{0}\" command").format( self.name) raise OperationError(msg, exitStatus=UserExitStatus) if self.checkBinaries: for executable in [ 'vdodumpconfig', 'vdoforcerebuild', 'vdoformat' ]: if not MgmntUtils.which(executable): msg = _("executable '{0}' not found in $PATH").format( executable) raise OperationError(msg, exitStatus=SystemExitStatus) if self.requiresRunMode and Command.noRunMode(): msg = _("{0} command not available with --noRun").format(self.name) raise OperationError(msg, exitStatus=UserExitStatus)
def persist(self): """Writes out the Configuration if necessary. If the Configuration is read-only or has not been modified, this method will silently return. If Command.noRunMode is True, any new Configuration will be printed to stdout instead of the file. This method will generate an assertion failure if the configuration file is not open. """ if self._readonly: return if not self._dirty: self.log.debug("Configuration is clean, not persisting") return self.log.debug("Writing configuration to {0}".format(self.filepath)) if self._empty(): self._removeFile() return s = yaml.dump({"config": self}, default_flow_style=False) if Command.noRunMode(): print(_("New configuration (not written):")) print(s) self._dirty = False return newFile = self.filepath + ".new" if os.path.exists(newFile): os.remove(newFile) with open(newFile, 'w') as fh: # Write the warning about not editing the file. fh.write( "####################################################################" ) fh.write(os.linesep) fh.write("# {0}".format( _("THIS FILE IS MACHINE GENERATED. DO NOT EDIT THIS FILE BY HAND." ))) fh.write(os.linesep) fh.write( "####################################################################" ) fh.write(os.linesep) # Write the configuration, flush and sync. fh.write(s) fh.flush() os.fsync(fh) os.rename(newFile, self.filepath) self._fsyncDirectory() self._dirty = False
def _fsyncDirectory(self): """Open and issue an fsync on the directory containing the config file. """ dirname = os.path.dirname(self.filepath) if Command.noRunMode(): runCommand(['fsync', dirname]) return fd = os.open(dirname, os.O_RDONLY) try: os.fsync(fd) finally: os.close(fd)
def _removeFile(self): """Deletes the current configuration file. In noRun mode, pretend that we're doing an rm of the file.""" if Command.noRunMode(): runCommand(['rm', self.filepath]) return if os.path.exists(self.filepath): os.remove(self.filepath) self._fsyncDirectory() try: with FileLock(self.singletonLock, "r+") as f: del Configuration.modifiableSingltons[self.filepath] except KeyError: pass