def _system_daemon_prompt(): """Prompt user to see whether they want to run as a system daemon. Args: None Returns: None """ # Initialize key variables running_username = getpass.getuser() # Return if running as root. We'll run as a daemon if running_username == 'root': return # Get the user's intention prompt = input( 'Do you want switchmap-ng to start automatically ' 'after a reboot?: (Y, N) ') intention = prompt.strip() if bool(intention) is True and len(intention) == 1: response = intention.lower()[0] if response == 'n': return elif response == 'y': log_message = ( 'Run this script as the "root" user to ' 'get the automatic functionality.') log.log2die_safe(1012, log_message) log_message = 'Please answer "Y" or "N", and try again.' log.log2die_safe(1013, log_message)
def _get_daemon_username(): """Get the daemon's username. Args: None Returns: daemon_username: Username daemon will run as """ # Initialize key variables running_username = getpass.getuser() # If running as the root user, then the infoset user needs to exist if running_username == 'root': try: daemon_username = input( 'Please enter the username under which ' 'infoset-ng will run: ') # Get GID and UID for user _ = getpwnam(daemon_username).pw_gid except: log_message = ( 'User {} not found. Please try again.' ''.format(daemon_username)) log.log2die_safe(1019, log_message) else: daemon_username = running_username # Return return daemon_username
def log_directory(self): """Determine the log_directory. Args: None Returns: value: configured log_directory """ # Initialize key variables key = 'main' sub_key = 'log_directory' # Process configuration value = _key_sub_key(key, sub_key, self.config_dict) # Check if value exists if os.path.isdir(value) is False: log_message = ('log_directory: "{}" ' 'in configuration doesn\'t exist!').format(value) log.log2die_safe(1030, log_message) # Return return value
def _python(self): """Determine Python version. Args: None Returns: None """ # Initialize key variables valid = True major = 3 minor = 5 major_installed = sys.version_info[0] minor_installed = sys.version_info[1] # Determine whether python version is too low if major_installed < major: valid = False elif major_installed == major and minor_installed < minor: valid = False # Process validity if valid is False: log_message = ( 'Required python version must be >= {}.{}. ' 'Python version {}.{} installed' ''.format(major, minor, major_installed, minor_installed)) log.log2die_safe(1095, log_message) else: log_message = ( 'Python version {}.{}.' ''.format(major_installed, minor_installed)) setup.print_ok(log_message)
def __init__(self): """Function for intializing the class. Args: None Returns: None """ # Initialize key variables self.username = getpass.getuser() valid = True major = 3 minor = 5 major_installed = sys.version_info[0] minor_installed = sys.version_info[1] # Exit if python version is too low if major_installed < major: valid = False elif major_installed == major and minor_installed < minor: valid = False if valid is False: log_message = ( 'Required python version must be >= {}.{}. ' 'Python version {}.{} installed' ''.format(major, minor, major_installed, minor_installed)) log.log2die_safe(1027, log_message)
def _pip3_install(module): """Install python module using pip3. Args: module: module to install Returns: None """ # Find pip3 executable cli_string = 'which pip3' response = general.run_script(cli_string, die=False) # Not OK if not fount if bool(response['returncode']) is True: log_message = ('python pip3 not installed.') log.log2die_safe(1041, log_message) else: log_message = 'Python pip3 executable found.' setup.print_ok(log_message) # Determine version of pip3 cli_string = 'pip3 --version' response = os.popen(cli_string).read() version = response.split()[1] # Attempt to install module if version < '9.0.0': cli_string = 'pip3 list | grep {}'.format(module) else: cli_string = 'pip3 list --format columns | grep {}'.format(module) response = bool(os.popen(cli_string).read()) if response is False: # YAML is not installed try to install it cli_string = 'pip3 install --user {}'.format(module) response_install = general.run_script(cli_string, die=False) # Fail if module cannot be installed if bool(response_install['returncode']) is True: log_message = ('python pip3 cannot install "{}".'.format(module)) log.log2die_safe(1100, log_message) else: log_message = ( 'Python module "{}" is installed.'.format(module)) setup.print_ok(log_message) else: log_message = 'Python module "{}" is installed.'.format(module) setup.print_ok(log_message)
def setup(self): """Update the configuration with good defaults. Args: None Returns: None """ # Initialize key variables valid = True updated_list = [] config = copy.deepcopy(self.config) directory = self.directories[0] directory_keys = ['log_directory', 'cache_directory'] # Update log_directory and cache_directory if isinstance(config, dict) is True: if 'main' in config: for next_key in directory_keys: # Setup the log_directory to a known good default (updated, config) = self._create_directory_entries( next_key, config) updated_list.append(updated) else: valid = False else: valid = False # Gracefully exit if things are not OK if valid is False: log_message = ( 'Configuration files found in {} is invalid' ''.format(self.directories)) log.log2die_safe(1015, log_message) # Update configuration file if required if True in updated_list: for next_directory in self.directories: # Delete all YAML files in the directory general.delete_yaml_files(next_directory) # Write config back to directory filepath = ('%s/config.yaml') % (directory) with open(filepath, 'w') as outfile: yaml.dump(config, outfile, default_flow_style=False)
def read_yaml_files(directories): """Read the contents of all yaml files in a directory. Args: directories: List of directory names with configuration files Returns: config_dict: Dict of yaml read """ # Initialize key variables yaml_found = False yaml_from_file = '' all_yaml_read = '' # Check each directory in sequence for config_directory in directories: # Check if config_directory exists if os.path.isdir(config_directory) is False: log_message = ('Configuration directory "%s" ' 'doesn\'t exist!' % config_directory) log.log2die_safe(1009, log_message) # Cycle through list of files in directory for filename in os.listdir(config_directory): # Examine all the '.yaml' files in directory if filename.endswith('.yaml'): # Read YAML data filepath = ('%s/%s') % (config_directory, filename) yaml_from_file = read_yaml_file(filepath, as_string=True) yaml_found = True # Append yaml from file to all yaml previously read all_yaml_read = ('%s\n%s') % (all_yaml_read, yaml_from_file) # Verify YAML files found in directory if yaml_found is False: log_message = ('No files found in directory "%s" with ".yaml" ' 'extension.') % (config_directory) log.log2die_safe(1010, log_message) # Return config_dict = yaml.load(all_yaml_read) return config_dict
def __init__(self): """Function for intializing the class. Args: None Returns: None """ # Initialize key variables running_username = getpass.getuser() daemon_username = configuration.Config().username() self.root_directory = general.root_directory() switchmap_user_exists = True self.switchmap_user = None self.running_as_root = False # Set the username we need to be running as if running_username == 'root': try: # Get GID and UID for user self.switchmap_user = daemon_username self.gid = getpwnam(self.switchmap_user).pw_gid self.uid = getpwnam(self.switchmap_user).pw_uid except KeyError: switchmap_user_exists = False # Die if user doesn't exist if switchmap_user_exists is False: log_message = ( 'User {} not found. Please try again.' ''.format(self.switchmap_user)) log.log2die_safe(1129, log_message) else: self.switchmap_user = daemon_username # If running as the root user, then the switchmap user needs to exist if running_username == 'root': self.running_as_root = True return
def read_yaml_file(filepath, as_string=False): """Read the contents of a YAML file. Args: filepath: Path to file to be read as_string: Return a string if True Returns: result: Dict of yaml read """ # Initialize key variables if as_string is False: result = {} else: result = '' # Read file if filepath.endswith('.yaml'): try: with open(filepath, 'r') as file_handle: yaml_from_file = file_handle.read() except: log_message = ('Error reading file %s. Check permissions, ' 'existence and file syntax.' '') % (filepath) log.log2die_safe(1024, log_message) # Get result if as_string is False: result = yaml.load(yaml_from_file) else: result = yaml_from_file else: # Die if not a YAML file log_message = '{} is not a YAML file.'.format(filepath) log.log2die_safe(1065, log_message) # Return return result
def delete_files(directory, extension='.yaml'): """Delete all files of a specfic extension in a directory. Args: directory: Directory name extension: File extension Returns: None """ # Determine whether directory is valid if os.path.isdir(directory) is False: log_message = ('Directory %s does not exist') % (directory) log.log2die_safe(1007, log_message) # Get list of files filelist = [ next_file for next_file in os.listdir(directory) if next_file.endswith(extension) ] # Delete files for delete_file in filelist: file_path = ('%s/%s') % (directory, delete_file) try: if os.path.isfile(file_path): os.unlink(file_path) except Exception as exception_error: log_message = ('Error: deleting files in %s. Error: %s') % ( directory, exception_error) log.log2die_safe(1014, log_message) except: log_message = ('Unexpected error') log.log2die_safe(1006, log_message)
def _install_pip3_packages(self): """Install PIP3 packages. Args: None Returns: None """ # Initialize key variables username = self.username # Don't attempt to install packages if running in the Travis CI # environment if 'TRAVIS' in os.environ and 'CI' in os.environ: return # Determine whether PIP3 exists print_ok( 'Installing required pip3 packages from requirements.txt file.') pip3 = general.search_file('pip3') if pip3 is None: log_message = ('Cannot find python "pip3". Please install.') log.log2die_safe(1052, log_message) # Install required PIP packages requirements_file = ( '%s/requirements.txt') % (general.root_directory()) if username == 'root': script_name = ( 'pip3 install --upgrade --requirement %s' '') % (requirements_file) else: script_name = ( 'pip3 install --user --upgrade --requirement %s' '') % (requirements_file) general.run_script(script_name)
def _systemd(self): """Determine whether systemd is installed. Args: None Returns: None """ # Initialize key variables. directory = '/etc/systemd/system' # Do nothing if this is not the root user. username = getpass.getuser() if username != 'root': return # Test if os.path.isdir(directory) is True: setup.print_ok('Systemd installed.') else: log_message = 'Systemd not installed. Directory {} not found' log.log2die_safe(1234, log_message)
def _file_permissions(self): """Set file permissions. Args: None Returns: None """ # Initialize key variables switchmap_user = self.switchmap_user root_directory = self.root_directory # Prompt to change ownership of root_directory groupname = grp.getgrgid(self.gid).gr_name response = input( 'Change ownership of {} directory to user:{} group:{} (y,N) ?: ' ''.format(root_directory, switchmap_user, groupname)) # Abort if necessary if response.lower() != 'y': log_message = ('Aborting as per user request.') log.log2die_safe(1130, log_message) # Change ownership of files under root_directory for parent_directory, directories, files in os.walk(root_directory): for directory in directories: os.chown(os.path.join( parent_directory, directory), self.uid, self.gid) for next_file in files: os.chown(os.path.join( parent_directory, next_file), self.uid, self.gid) # Change ownership of root_directory os.chown(root_directory, self.uid, self.gid)
def _key_sub_key(key, sub_key, config_dict, die=True): """Get config parameter from YAML. Args: key: Primary key sub_key: Secondary key config_dict: Dictionary to explore die: Die if true and the result encountered is None Returns: result: result """ # Get result result = None # Verify config_dict is indeed a dict. # Die safely as log_directory is not defined if isinstance(config_dict, dict) is False: log.log2die_safe(1021, 'Invalid configuration file. YAML not found') # Get new result if key in config_dict: # Make sure we don't have a None value if config_dict[key] is None: log_message = ( 'Configuration value {}: is blank. Please fix.' ''.format(key)) log.log2die_safe(1037, log_message) # Get value we need if sub_key in config_dict[key]: result = config_dict[key][sub_key] # Error if not configured if result is None and die is True: log_message = ( '%s:%s not defined in configuration') % (key, sub_key) log.log2die_safe(1016, log_message) # Return return result