def doReset(): activeVersion = getActiveMongoVersion() # if not a version activated, then abort if activeVersion == '': print('No currently activated MongoDB Version') return False # Admin required if not lxtools.getIfAdmin(): print(config.getMessage('REQUIREADMIN')) return False # If folder exits but not an symlink, then abort if activeVersion is False: print('ERROR: Folder is not a symlink.') return False print('Deactivate MongoDB v' + activeVersion) # Run Script file pkginfo = lxtools.loadjson(os.path.join(mongosymlink, config.getConfigKey('configfile'))) package.runScript(pkginfo, ['remove', 'safe', 'hidden']) # Check if *all* symbolic links removed, when not remove it symlinks = config.getConfigKey('mongo.links', None) if symlinks: for names in symlinks: target = os.path.join(symlinks[names]['target'], names) if os.path.exists(target) and lxtools.getIfSymbolicLink(target): os.remove(target) if not resetMongo(): return False
def upgrade(): rootdir = lxtools.getBaboonStackDirectory() prev_catalogfilename = os.path.join(rootdir, config.lxPreviousPackage) # No Upgrade required if not os.path.isfile(prev_catalogfilename): return False # Check if admin if not lxtools.getIfAdmin(): print('Catalog Upgrade required!', config.getMessage('REQUIREADMIN')) return True catalogdata = lxtools.loadjson(prev_catalogfilename, False) pkgdata = catalogdata.get('packages', {}) for pkgname in pkgdata: if getIfPackageInstalled(pkgdata[pkgname]): pkgfilename = os.path.join(rootdir, pkgdata[pkgname].get('dirname'), config.getConfigKey('configfile')) if not os.path.isfile(pkgfilename): pkginfo = pkgdata[pkgname].copy() # Add some informations pkginfo['name'] = pkgname pkginfo['bbsversion'] = catalogdata.get('version', '0.0.0') if not lxtools.savejson(pkgfilename, pkginfo): print('Upgrade failure...') return False os.remove(prev_catalogfilename) print('Upgrade successfull...') return True
def getIfMongoVersionAvailable(mongoversion): if os.path.exists(os.path.join(mongobasedir, mongoversion)): pkginfo = lxtools.loadjson( os.path.join(mongobasedir, mongoversion, config.getConfigKey('configfile')), reporterror=False ) # has package file if pkginfo: binlist = pkginfo.get('binary', None) # Check if binarys exists if binlist: if isinstance(binlist, str): binlist = [binlist] if isinstance(binlist, list): for binname in binlist: if not os.path.exists(os.path.join(mongobasedir, mongoversion, binname)): return False return True # No installed return False
def loadPackage(self, filename, mergedata=False): if os.path.isfile(filename): tmppkgdata = lxtools.loadjson(filename) # Merge data or overwrite all if mergedata: self.merge(tmppkgdata) else: self.__packagedata = tmppkgdata self.refresh()
def getRemoteCatalog(localcatalogonly=False): catalog = dict() bbscatalogfile = os.path.join(lxtools.getBaboonStackDirectory(), 'baboonstack.package.conf') # First, try to read local package file if not exists then if os.path.exists(bbscatalogfile): catalogdata = lxtools.loadjson(bbscatalogfile) packages = catalogdata.get('packages', {}) for pkgname in packages: catalog[pkgname] = { 'version': [packages[pkgname].get('version')], 'source': 'catalog', 'info': packages[pkgname] } if localcatalogonly: return catalog # Download Filelist data = lxtools.getRemoteData(config.lxServer + '/') # If Exception occured if data == -1: return [] # Gets the Package Name Mask for this OS packagenamemask = str( config.getConfigKey('packagemask') ).format( lxtools.getOsArchitecture() ) # Get the available packages for this OS filelist = regex.findall('">(' + packagenamemask + ')<\/a', data) filelist.sort() # Add all versions for entry in filelist: a = os.path.splitext(entry)[0].split('-') if a[0] == 'baboonstack': continue if a[0] not in catalog: catalog[a[0]] = { 'version': [], 'source': 'server' } catalog[a[0]]['version'].append(a[1][1:]) catalog[a[0]]['source'] = 'server' return catalog
def doUpgrade(): if os.path.isdir(mongosymlink) and not lxtools.getIfSymbolicLink(mongosymlink): # Upgrade print('Upgrade needed...') # Check if admin if not lxtools.getIfAdmin(): print(config.getMessage('REQUIREADMIN')) return False # Load package file pkginfo = lxtools.loadjson(os.path.join(mongosymlink, config.getConfigKey('configfile'))) mongoversion = pkginfo.get('version', None) # Execute Patches patches = config.getConfigKey('mongo.patches', None) patch.doPatch(mongosymlink, patches) # Stop Service/Daemon and de-register Service/Daemon, safe-remove print('Stop Service/Daemon...') package.runScript(pkginfo, ['remove', 'safe', 'hidden']) # Check if *all* symbolic links removed, when not remove it symlinks = config.getConfigKey('mongo.links', {}) if symlinks: for names in symlinks: target = symlinks[names]['target'] if os.path.exists(target) and lxtools.getIfSymbolicLink(target): os.remove(target) # Move Directory to mongodb/{version}/ print('Move files...') mongodir = os.path.join(mongobasedir, mongoversion) # Create new mongodb directory and move installed version os.makedirs(mongobasedir) os.rename(mongosymlink, mongodir) # Create Symlink print('Create symlinks...') lxtools.setDirectoryLink(mongosymlink, mongodir) # Start Daemon/Service print('Start Service/Daemon...') package.runScript(pkginfo, ['install', 'hidden']) print('Done') return True else: return None
def getLocalCatalog(scanfolders=True): rootdir = lxtools.getBaboonStackDirectory() catalog = dict() files = os.listdir(rootdir) # First, try to read local package file if not exists then if os.path.exists(os.path.join(rootdir, 'baboonstack.package.conf')): catalogdata = lxtools.loadjson(os.path.join(rootdir, 'baboonstack.package.conf')) pkgdata = catalogdata.get('packages', {}) for pkgname in pkgdata: pkginfo = pkgdata.get(pkgname, {}) pkginfo['name'] = pkgname catalog[pkgname] = BaboonStackPackage(pkginfo) if scanfolders: for entry in files: fullpath = os.path.join(rootdir, entry) if not os.path.isdir(fullpath): continue packagefile = os.path.join(fullpath, 'package.bbs.conf') if os.path.isfile(packagefile): pkgdata = BaboonStackPackage({}) pkgdata.loadPackage(packagefile) packagename = pkgdata.getPackageName() if packagename is None or not pkgdata.getIfInstalled(): continue # if package infos already set, then merge data if packagename in catalog and isinstance(catalog[packagename], BaboonStackPackage): catalog[packagename].loadPackage(packagefile, True) else: catalog[packagename] = pkgdata return catalog
def doChange(version): activeVersion = getActiveMongoVersion() # Admin required if not lxtools.getIfAdmin(): print(config.getMessage('REQUIREADMIN')) return False # If folder exits but not an symlink, then abort if activeVersion is False: print('ERROR: Folder is not a symlink.') return False # Version already active if activeVersion == version: print('Version', version, 'already active.') return False # If version locally available if not getIfMongoVersionAvailable(version): print('Version', version, 'not available locally.') return False # Check if selected version currently activ in pidlist pidfile = 'mongo-' + version + '.pids' pidlist = lxtools.loadFileFromUserSettings(pidfile, returntype=[]) if len(pidlist) != 0: # Get a list with active pids from a list with pids alive = lxtools.getActiveProcessFromPidList(pidlist) if len(alive) != 0: print('Version is in use and can not be registered as a service.') return False # if version already set, then deactivate if activeVersion != '': doReset() # Mongo dir mongodir = os.path.join(mongobasedir, version) # Create Symlink print('Activate Mongo v' + version) lxtools.setDirectoryLink(mongosymlink, mongodir) # Run Script file pkginfo = lxtools.loadjson(os.path.join(mongosymlink, config.getConfigKey('configfile'))) package.runScript(pkginfo, ['install', 'hidden']) # Check if *all* symbolic links successfully linked symlinks = config.getConfigKey('mongo.links', None) if symlinks is not None: print('Create symlinks...') for names in symlinks: source = os.path.join(mongosymlink, symlinks[names]['source'], names) target = os.path.join(symlinks[names]['target'], names) # Link if not lxtools.setDirectoryLink(target, source): raise Exception('Link creation failed!\n' + source + ' => ' + target) print('\nDone, nice!') pass
def install(pkgname, options=list()): if pkgname is None: return False # if pkgname is list, then install multiple if isinstance(pkgname, list): pkgcnt = 0 for name in pkgname: print('Install package "' + name + '"...') if install(name, options): pkgcnt += 1 print('') print(' {0} of {1} packages successfully installed'.format(str(pkgcnt), str(len(pkgname)))) return True # Install ALL packages? if pkgname == '': if 'force' not in options and 'ask' not in options: options.append('ask') pkgname = [] for pkg in localcatalog: # Only install if not installed locally if not localcatalog[pkg].getIfInstalled(): pkgname.append(pkg.get('name', None)) if len(pkgname) == 0: print('Sorry, no packages available to install.') return False # Rerun return install(pkgname, options) # # Start install single package # # Check, if package available if pkgname not in remotecatalog: print('Unknow Package "' + pkgname + '"...') return False # pkginfo = {} # Collect pkginfo and if package already installed if pkgname in localcatalog: if localcatalog[pkgname].getIfInstalled(): print('Package "' + pkgname + '" already installed locally...') return False pkgdata = remotecatalog[pkgname] latestversion = getLastVersion(pkgdata) fullpackagename = str(config.getConfigKey('package')).format( pkgname, latestversion, lxtools.getOsArchitecture() ) print('Source:', pkgdata.get('source', '<unknow>')) # Get catalog info # if pkgdata['source'] == 'catalog': pkginfo = pkgdata.get('info', {}) # Check if admin if not lxtools.getIfAdmin(): print(config.getMessage('REQUIREADMIN')) return False # Ask if 'ask' in options: key = lxtools.readkey('Do you really want to install "' + pkgname + '"...', 'Yn') if key == 'n': return False # If Download require if pkginfo.get('nodownload', False) is True: # No Download require, then create dir and exit basedir = os.path.join(lxtools.getBaboonStackDirectory(), pkginfo.get('dirname')) print('Create Directory...') try: os.mkdir(basedir, 0o755) # Execute scripts runScript(pkginfo, ['install']) except BaseException as e: print('ERROR:', e) return False print('Done...') return True # # Download Filelist # if not getLatestRemoteVersion(fullpackagename): # print('SERVER ERROR: Package not found on server...') # return False # Retrieve package checksum packagechecksum = getRemoteChecksum(fullpackagename) # Build url = config.lxServer + '/' + fullpackagename dirname = None iserror = False localpacketname = os.path.join(tempfile.gettempdir(), fullpackagename) # Download Packet with Progressbar print('Download ' + fullpackagename + '...') result = lxtools.getRemoteFile(url, localpacketname) # Exception or canceled if result == -1: return False # Check package checksum if packagechecksum: print('Verify Checksum...') localchecksum = lxtools.getSHAChecksum(localpacketname) # Check Checksum if localchecksum == packagechecksum: print('Checksum are correct...') else: print('Checksum missmatch... Abort!') print('Filename ' + fullpackagename) print('Remote SHA' + str(packagechecksum)) print('Local SHA' + localchecksum) return False else: print('WARNING: No Checksum for this package available...') # Extract Archive Package try: print('Extracting...') tempdirectory = tempfile.mkdtemp() archive_filelist = [] # Unix specified if sys.platform.startswith('linux') or sys.platform == 'darwin': # Extract files mytar = tarfile.open(localpacketname) # Find and Read package description file, if exists for tarinfo in mytar: if os.path.basename(tarinfo.name) == config.getConfigKey('configfile', 'package.bbs.conf'): print('Read package description file...') try: # Extract file mytar.extract(tarinfo.name, tempdirectory) # Read package pkginfo = lxtools.loadjson(os.path.join(tempdirectory, tarinfo.name), True) except BaseException as e: print(e) return False # Exit break # Get dirname dirname = os.path.join(pkginfo.get('dirname'), '') # Check dependencies, if set if getIfDependenciesInstalled(pkginfo): # Get the filelist from tarfile for tarinfo in mytar: normpath = os.path.normpath(tarinfo.name) if normpath.startswith(dirname): archive_filelist.append(normpath[len(dirname):]) # Extract files try: mytar.extractall(lxtools.getBaboonStackDirectory()) except BaseException as e: print('Error in TAR, see error below.') print(e) else: iserror = True mytar.close() # Windows specified if sys.platform == 'win32': if zipfile.is_zipfile(localpacketname): myzip = zipfile.ZipFile(localpacketname, 'r') # Find and Read package description file, if exists for filename in myzip.namelist(): if os.path.basename(filename) == config.getConfigKey('configfile', 'package.bbs.conf'): print('Read package description file...') try: # Extract file myzip.extract(filename, tempdirectory) # Read package pkginfo = lxtools.loadjson(os.path.join(tempdirectory, filename), True) except BaseException as e: print(e) return False # Exit break # Get dirname dirname = os.path.join(pkginfo.get('dirname'), '') # Check dependencies, if set if getIfDependenciesInstalled(pkginfo): # Get the filelist from zipfile for filename in myzip.namelist(): normpath = os.path.normpath(filename) if normpath.startswith(dirname): archive_filelist.append(normpath[len(dirname):]) # Extract files try: myzip.extractall(lxtools.getBaboonStackDirectory()) except BaseException as e: print('Error in ZIP, see error below.') print(e) else: iserror = True myzip.close() else: print('ERROR: Archive is not a ZIP File.') return False # Remove temporary directory lxtools.rmDirectory(tempdirectory) # If error occured if iserror: return False # Has dirname if not dirname: print('ERROR: No "dirname" in description file...') return False # Some file and directories will be include or exclude for removing files_rules = pkginfo.get('files', None) if files_rules is not None: files_includes = files_rules.get('include', []) files_excludes = files_rules.get('exclude', []) # Include files or directory if files_includes: # If single string, then build array if isinstance(files_includes, str): files_includes = [files_includes] if isinstance(files_includes, list): for fileentry in files_includes: archive_filelist.append(os.path.normpath(fileentry)) # Exclude files or directory if files_excludes: # If single string, then build array if isinstance(files_excludes, str): files_excludes = [files_excludes] if isinstance(files_excludes, list): for fileentry in files_excludes: fullname = os.path.normpath(fileentry) # Remove every item tmpfilelist = archive_filelist.copy() for archiveentry in tmpfilelist: if str(archiveentry).startswith(fullname): archive_filelist.remove(archiveentry) # Save filelist into program directory for remove if len(archive_filelist) != 0: lstname = os.path.join(lxtools.getBaboonStackDirectory(), dirname, 'files.lst') try: fileslst = open(lstname, 'w') fileslst.write('\n'.join(archive_filelist)) fileslst.close() except BaseException as e: print('Error while saving filelist!') print(e) print('Installing...') scriptoption = ['install'] # Execute scripts runScript(pkginfo, scriptoption) except BaseException as e: print('ERROR:', e) return False lxtools.cleanUpTemporaryFiles() print('Done...') return True