def installApplication(self, installDir, testmode): """ Manager.installApplication Installs the application by performing the following steps: - checks to see if the installation directory is writable - loads metadata - checks if enough disk space is available - checks to see if this is an incremental installation - looks for the base disribution for this release - checks for previous installation of this package and checks the md5sum <not implemented> - unpacks the installation package - publishes package metadata - sets up the environment scripts and runs setup scripts - creates links and checks installation size """ if notWritable(installDir): sys.exit(notWritable(installDir)) # Absolutize path if needed: if not os.path.isabs(installDir): installDir = os.path.abspath(installDir) # Extract metadata from distribution: metadata = loadMetadata(getMetaDataFile(), archive = self.currentRequest.getDarFile()) infoOut('Loaded DAR metadata from '+self.currentRequest.getDarFile()) # If in test mode, print out users info and exit: if testmode: print metadata.userInfo() return # Check that there is enough space in the installation directory: available = spaceLeft(installDir) installSize = float(metadata.getInstallationSize()) if available < installSize: sys.exit('Not enough space on the disk!\n Installation size: ' \ + str(installSize) + ' KB\n Available: ' + str(available) + ' KB') self.timingLog('Checked space left in '+installDir) ########################################## # Handling incremental DARballs: ########################################## # Check if darball metadata contain a reference to a base dar: baseDar = metadata.getBaseDar() if baseDar: infoOut("This is incremental distribution based on "+baseDar) # This is an incremental darball, so # we need matching base installation. baseInstallation = self.currentRequest.baseDar if not baseInstallation: usageError ('Please specify a base .') # Lookup for base installation in the installation pool: # baseInstallation = self.findBaseInstallation(self.distPool, # baseDar) # if not baseInstallation: # sys.exit( 'Could not find base installation for ' + # baseDar + ' # in '+self.sharedPool) infoOut("(todo)Verifying base installation "+baseInstallation) ########################################## # General actions for all DARballs: ########################################## # Check if the installation already exists: releaseInstTop = os.path.join(installDir, metadata.getVersionTag(), metadata.getArchitecture()) if os.path.exists( releaseInstTop): # TODO: validate the installation using md5sum and # tell user the results sys.exit("ERROR: You already have installation here: \n " \ +releaseInstTop+"\nExiting ....\n") # Unpack darball infoOut('Unpacking '+self.currentRequest.getDarFile()+' .... ') unpackCommand = 'tar -xz -C ' + \ installDir + ' -f ' + \ self.currentRequest.getDarFile() (status, out) = commands.getstatusoutput(unpackCommand) # Check that in unpacked into toInstallDir as expected: if status: # failed if out: # save command output in the logfile: unpackLogfile = os.path.join(self.logdir, 'dar_unpack.log') tarlog = open(unpackLogfile, 'w') tarlog.write('Output from unpacking command:\n' + \ unpackCommand + '\n' + out ) tarlog.close() sys.exit ('Unpacking failed with exit status ' + status + \ '\nOutput can be found in \n' + unpackLogfile ) elif not os.path.isdir(releaseInstTop): sys.exit ('Can not find '+releaseInstTop) # Link to a base installation for incremental darballs if baseDar: infoOut("Create a link to base installation:\n ln -s " +baseInstallation+'/shared '+releaseInstTop+'/base') os.symlink(baseInstallation+'/shared', releaseInstTop+'/base') # Set up environment scripts: infoOut("Setting up the installation") templateStub = os.path.join(releaseInstTop, getSetupScriptBasename()) newSetupScriptStub = os.path.join(releaseInstTop, 'envSetup') helpText = self.updateSetupScripts(\ templateStub, \ releaseInstTop, \ newSetupScriptStub ) # For compatibility with the old Production tools: oldSetupScriptStub = os.path.join(releaseInstTop, metadata.getVersionTag() + '_env') self.updateSetupScripts(\ templateStub, \ releaseInstTop, \ oldSetupScriptStub ) # Move script templates to the DAR admin directory. #infoOut('Removing setup scripts templates ...') cmd = 'mv ' + templateStub + '.*sh' + ' ' \ + installDir + '/' + getDarDirName() (status, out)=commands.getstatusoutput(cmd) if status != 0: # did not succeed DARInternalError("In installApplication: " + "doing command" + cmd + "\ncommand output :\n" + out) #infoOut("(todo) Do md5sum check of BOM in resulting installation") #infoOut("(todo) If successful, " + # "register installation in publishing service ") self.publishMetadata(installDir + '/' + getDarDirName()) # Publish installation metadata: self.publishMetadata(installDir + '/' + getDarDirName()) #Print out runtime environment setup help (and exit): infoOut(helpText) infoOut("Installation completed.")
def prepareDistribution(self, method = 'copy'): """ Manager.prepareDistribution: Creates DARball structure according to current request, using copy, or link method. """ # Check how much space is left in tmp dir, # where the darball will be built: spaceLeft(self.tmpdir) self.timingLog('Checked space left in '+self.tmpdir) # If incremental darbal was requested, get its metadata, # and fill up base bomdictionary baseDar = self.currentRequest.baseDar self.darMeta.setBaseDar(baseDar) if baseDar: if os.path.isdir(baseDar): # This should be an installation directory: bomFile = baseDar+'/' + getBOMFileName() if os.path.isfile(bomFile): # Create base bom dictionary directly from file for entry in open(bomFile,'r').readlines(): # a list of lines (md5, entryPath) = string.split(entry) self.baseBomDict[entryPath] = md5 else: raise InputError(baseDar, 'Could not find ' + getBOMFileName() + ' here.') else: if os.path.isfile(baseDar): # This should be a DARball: baseDarball = baseDar else: # This should be a release tag of a base darball # available from the dar pool. # Lookup for base darball in the distribution pool: if notReadable(self.distPool): sys.exit(notReadable(self.distPool)) baseDarball = self.findBaseDarball(self.distPool, baseDar) if not baseDarball: sys.exit( 'Could not find base distribution for ' \ +baseDar+' in '+self.sharedPool) # Create base bom dictionary on the flight from the archive: result = readFileFromArchive(baseDarball, getBOMFileName()) for entry in string.split(result,'\n'): md5, entryPath = string.split(entry) self.baseBomDict[entryPath] = md5 # Now create DAR directory structure: self.dar = Structure(self.blddir, self.currentRequest, method, baseBom = self.baseBomDict) self.timingLog('Created DAR in ' + self.blddir + ' using ' + method + ' method') instDir = self.dar.getTopInstDir() if method == 'copy': self.timingLog('Counted install. size ' + 'before cleanup in shared dir') # Make cleanup and create BOM only for the FSO image (shared # between the environment variables): cleanup(self.dar.getSharedTop(), os.path.join(self.dar.getTopInstDir(), getBOMFileName())) self.timingLog('Removed duplicates and created BOM for ' + self.dar.getSharedTop()) size = noteSize(instDir) self.timingLog('Counted size after cleanup in ' + self.dar.getSharedTop()) self.darMeta.setInstallationSize(size) # fakeScram() # including scram runtime command, which may replace setup scripts. self.saveMetadata(os.path.join(self.dar.getTopInstDir(), getMetaDataFile())) # - saves into metadata file info about creation of a darball, # project conifguration info. Adds a spec file (and darInput in # scram mode). DAR info and its source code go here. self.createReadmeFile()