Source code for mylinux.Controller

from __future__ import absolute_import

from . import view
from . import model
from .constants import error as ERR

from mylinux.libs import AppErr

try:
	input = raw_input
except NameError:
	input = input

[docs]class Controller(object): """Main MVC controller of the package. Args: filesPath (str): Path to the file where main data is located. Attributes: _Controller__inited (boo): If False class was not inited yet. Files (ins): Files instance. Raises: AppErr.developer: If singletone was allready inited. Note: This class is singletone which checks ``__inited``, if instance was allready created. """ __inited = False def __init__(self, filesPath): if not Controller.__inited: Controller.__inited = True self.Files = model.Files(mainPath=filesPath) else: raise AppErr.developer(ERR.singletone)
[docs] def execute(self, ACTION, CONFIG=False, PACKAGE_NAMES=None): """Executing actions on packages. Args: ACTION (str): Execute action on packages. CONFIG (boo): If action will be made on package config too. PACKAGE_NAMES (arr-str): Name of package folder. Other Parameters: Start TUI if you want to select packages. Create checks if action is allowed for all selected packages. Execute action on packages. Make report of executing. """ if not PACKAGE_NAMES: PACKAGE_NAMES = self.__tuiSelect(ACTION, CONFIG) if not PACKAGE_NAMES: return self.__postSelectCheck(ACTION, CONFIG, PACKAGE_NAMES) self.__executeSelected(PACKAGE_NAMES) self.__postExecuteReport(PACKAGE_NAMES)
[docs] def create(self, PACKAGE_NAME): """Guide to create new package. Args: PACKAGE_NAME (str): Package to be created. Other Parameters: Get existing packages. Check if candidate already exist. Start TUI for input package info. Make file structure for package. """ existingPackages = self.Files.getPackageNames() if PACKAGE_NAME in existingPackages: view.Tli.raiseError( AppErr.user, 'Create package', ['FAIL', PACKAGE_NAME, ERR.Format.alreadyExistIn('packages')] ) else: returned = self.__tuiCreate(PACKAGE_NAME) self.Files.createPackage( name=PACKAGE_NAME, info=returned['info'], scripts=returned['scripts'] )
[docs] def logs(self, PACKAGE_NAME): """Show logs Args: PACKAGE_NAME (str): Package name Other Parameters: Start TUI for logs """ self.__tuiLogs(PACKAGE_NAME)
[docs] def script(self, SCRIPT_NAME): """Execute main mylinux scripts Args: SCRIPT_NAME (str): Name of the script that is located in base scripts folder Other Parameters: Get info from the script. Execute script line by line. Print report """ report = [] executor = model.linux.Executor() script = self.Files.getScript(SCRIPT_NAME) for i, cmdArray in enumerate(script.cmdArrays): executor.cwd = self.Files.scriptsPath passed, stdout, stderr = executor.execute(cmdArray) if passed: report.append(['PASS', ' '.join(cmdArray), stdout.split('\n')[0]]) for stdout_line in stdout.split('\n')[1:-1]: report.append(['', 'PASS', stdout_line]) else: report.append(['ERROR', ' '.join(cmdArray), stderr.split('\n')[0]]) for stdout_line in stderr.split('\n')[1:-1]: report.append(['', 'ERROR', stdout_line]) view.Tli.printReport( '"{}" script executing'.format(SCRIPT_NAME), report, ['Status', 'Code', 'stdout||stderr'] )
[docs] def test(self): """Make tests on already installed packages. Other Parameters: Get installed packages. Execute test script for each package. Make report. """ report = [] packagesNames = self.Files.installed.getNames() executor = model.linux.Executor() for package in self.Files.getPackages(packagesNames): executor.cwd = package.scriptsPath passed, stdout, stderr = executor.executeArrays( [ ['python', package.getScript('test.py').path] ] ) if passed: passed = 'PASS' else: passed = 'ERROR' report.append([passed, package.name, stderr]) view.Tli.printReport( 'Installed packages', report, ['Status', 'Package', 'stderr'] )
[docs] def check(self): """Check for errors for installed packages. Other Parameters: Check config/package state for every installed package. Make report. """ report = [] for packageName in self.Files.installed(): configState = self.Files.installed[packageName]['configState'] packageState = self.Files.installed[packageName]['packageState'] state = 'OK' if configState != 'ok' or packageState != 'ok': if configState == 'error' or packageState == 'error': state = 'ERROR' else: state = 'WARNING' report.append([state, packageName, packageState, configState]) view.Tli.printReport('Installed packages check', report, headers=['Status', 'Package', 'packageState', 'configState'])
def __tuiSelect(self, ACTION, CONFIG): """Start TUI for selecting packages. Args: ACTION (str): Joust for user visualization in TUI. CONFIG (str): Joust for user vis. in TUI Return: Arr-str of selected packages names. Other Parameters: Get packages base on action and config. Start TUI for selecting packages. """ # Basic filtering for qui view if ACTION != 'install': packages = self.Files.getPackages(self.Files.installed()) else: packages = self.Files.packages returnedValues = view.Tui.runSelectApp( modelValues={ 'action': ACTION, 'packages': packages, 'modules': self.Files.getModules(), 'classes': self.Files.getClasses(), 'packageNames': self.Files.getPackageNames(), 'packageInfos': self.Files.getInfoValues(), 'packageStates': self.Files.installed.getStates( packageNames=self.Files.getPackageNames(), key='packageState', filler='' ), 'configStates': self.Files.installed.getStates( packageNames=self.Files.getPackageNames(), key='configState', filler='' ) } ) return returnedValues['packageNames'] def __postSelectCheck(self, ACTION, CONFIG, PACKAGE_NAMES): """Post check after selection. Args: ACTION (str): Action that were executed. CONFIG (boo): Were action done ono config too? PACKAGE_NAMES (arr-str): Action were done on these packages. Other Parameters: Check existance of packages in package folder. Check existance in installed and permissions of executing action. If checks fails show user error report. Override selected package installed flags for them to be executed. """ error = [] # Check existance in packages for packageName in PACKAGE_NAMES: if not packageName in self.Files.getPackageNames(): error = ['FAIL', packageName, ERR.Format.notExistIn('packages')] # check existance in installed and permission to be updated/created... self.Files.installed.createOrUpdateSelected( config=CONFIG, action=ACTION, packageNames=PACKAGE_NAMES ) if error: view.Tli.raiseError( AppErr.user, 'Post select check', ['FAIL', packageName, ERR.Format.alreadyExistIn('installed')], headers=['Status', 'Package', 'Message'] ) else: self.Files.installed.override() def __executeSelected(self, PACKAGE_NAMES): """Execute selected packages Args: PACKAGE_NAMES (arg-str): Execute selected package names. Other Parameters: Make execute decisions for packages. Execute package scripts with executor. Update package info data in installed. Override installed data. If user want to exit wait for data to be writen. If user wants really to exit raise user error. """ executor = model.linux.Executor() packages = self.Files.getPackages(PACKAGE_NAMES) executor.status['count_all'] = len(PACKAGE_NAMES) for packageCount, package in enumerate(packages): executor.cwd = package.scriptsPath executor.status['name'] = package.name executor.status['count'] = packageCount + 1 decision = self.Files.installed.decidePackageExecution(package.name) # Required to be filled... pass_package = None stdout_package = '' stderr_package = '' pass_config = None stdout_config = '' stderr_config = '' # Executing for decisions if decision == 'installAll': pass_package, stdout_package, stderr_package = executor.executeArrays( cmdArrays=package.getScript('package-install').cmdArrays ) if pass_package: pass_config, stdout_config, stderr_config = executor.executeArrays( cmdArrays=package.getScript('config-install').cmdArrays ) elif decision == 'purgeAll': pass_package, stdout_package, stderr_package = executor.executeArrays( cmdArrays=package.getScript('package-purge').cmdArrays ) if pass_package: pass_config, stdout_config, stderr_config = executor.executeArrays( cmdArrays=package.getScript('config-purge').cmdArrays ) elif decision == 'installConfig': pass_config, stdout_config, stderr_config = executor.executeArrays( cmdArrays=package.getScript('config-install').cmdArrays ) elif decision == 'purgeConfig': pass_config, stdout_config, stderr_config = executor.executeArrays( cmdArrays=package.getScript('config-purge').cmdArrays ) elif decision == 'updateConfig': pass_config, stdout_config, stderr_config = executor.executeArrays( cmdArrays=package.getScript('config-purge').cmdArrays ) if pass_config: pass_config, stdout_install, stderr_install = executor.executeArrays( cmdArrays=package.getScript('config-install').cmdArrays ) stdout_config += stdout_install stderr_config += stderr_install self.Files.installed.packageAfterExecution( packageName=package.name, stdout=stdout_package + stdout_config, stderr=stderr_package + stderr_config, err_package=not pass_package if pass_package != None else None, err_config=not pass_config if pass_config != None else None ) # Override the installed file self.Files.installed.override() #Todo: Add msg to the constants if executor.exit: exit = input('>>> Really want to exit? [y/*]: ') if exit == 'y': raise AppErr.user('Exit on user request...') def __postExecuteReport(self, PACKAGE_NAMES): """Post execute report for packages Args: PACKAGE_NAMES (arg-str): Package names to be subject of reporting. Other Parameters: Get packages states. Report all packages states and if they pass """ report = [] for packageName in PACKAGE_NAMES: packageState = self.Files.installed[packageName]['packageState'] configState = self.Files.installed[packageName]['configState'] if (packageState in ['ok','None']) and (configState in ['ok','None']): passed = 'PASS' else: passed = 'ERROR' report.append([ passed, packageName, packageState, configState, self.Files.installed[packageName]['stderr'] ]) view.Tli.printReport( 'Execution status', report, headers=['Status', 'Package name', 'Package', 'Config', 'stderr'] ) def __tuiCreate(self, PACKAGE_NAME): """Start TUI for package creation. Args: PACKAGE_NAME (str): Package to be created. Return: Dic object similar to argument ``modelValues``. For more info see source. Other Parameters: Start TUI for creation. Return all info obout the new package. """ returnedValues = view.Tui.runCreateApp( modelValues={ 'packageName': PACKAGE_NAME, 'hints': { 'moduleName': self.Files.getModules(), 'className': self.Files.getClasses() }, 'package-install': [ 'sudo apt-get install {0}'.format(PACKAGE_NAME) ], 'package-purge': [ 'sudo apt-get purge {0}'.format(PACKAGE_NAME) ], 'config-install': [ 'sudo mv {0} {1}'.format( self.Files.packagesPath + '/' + PACKAGE_NAME + '/data/*', '~/.' + PACKAGE_NAME + 'rc' ) ], 'config-purge': [ 'sudo rm -rf {0}'.format('~/.' + PACKAGE_NAME + 'rc') ], 'test.py': [ 'import os', '#Test config existance', 'os.path.exists()', '#Test package installation', 'os.call("{0} --version")'.format(PACKAGE_NAME) ] } ) return returnedValues def __tuiLogs(self, PACKAGE_NAME): """Start TUI for package log. Args: PACKAGE_NAME (str): Name of the installed package. Other Parameters: Get ``stderr`` and ``stdout`` info from package in installed. Start logs TUI. """ view.Tui.runLogsApp( modelValues={ 'packageName': PACKAGE_NAME, 'stdout': self.Files.installed[PACKAGE_NAME]['stdout'].split('\n'), 'stderr': self.Files.installed[PACKAGE_NAME]['stderr'].split('\n') } )