def _check_symlinks(etc_dir, daemons): """Ensure the files in the etc dir are symlinks. Args: etc_dir: The directory that the symlinks are located in symlink_dir: The directory that the symlinks point to daemons: The list of system daemons Returns: None """ for daemon in daemons: # Initialize key variables symlink_path = os.path.join(etc_dir, daemon) # Say what we are doing print('Checking if the {}.service file is a symlink '.format(daemon)) link = os.path.islink('{0}.service'.format(symlink_path)) if link is False: if getpass.getuser() != 'root': shared.log('Current user is not root') print('Creating symlink for {}'.format(daemon)) # Create symlink if it doesn't exist shared.run_script('systemctl enable {}'.format(daemon))
def installation_checks(): """Validate conditions needed to start installation. Prevents installation if the script is not run as root and prevents installation if script is run in a home related directory Args: None Returns: True: If conditions for installation are satisfied """ # Check user if getpass.getuser() != 'travis': if getpass.getuser() != 'root': shared.log('You are currently not running the script as root.\ Run as root to continue') # Check installation directory if os.getcwd().startswith('/home'): shared.log('''\ You cloned the repository in a home related directory, please clone in a\ non-home directory to continue''') # Check if virtualenv is installed try: import virtualenv except ModuleNotFoundError: print('virtualenv is not installed. Installing virtualenv') shared.run_script('pip3 install virtualenv')
def install_missing_pip3(package, pip_dir, verbose=True): """Automatically Install missing pip3 packages. Args: package: The pip3 package to be installed pip_dir: The directory the packages should be installed to Returns: True: if the package could be successfully installed """ # Validate pip directory if not os.path.isdir(pip_dir): shared.log('Pip directory is invalid') # Installs to the directory specified as pip_dir if the user is not travis username = getpass.getuser() if username == 'root': shared.run_script('''\ python3 -m pip install {0} -t {1} -U --force-reinstall'''.format(package, pip_dir), verbose=verbose) elif username == 'travis': shared.run_script( 'python3 -m pip install {0}'.format(package), verbose=verbose) else: shared.log('Installation user is not "root" or "travis"')
def run_systemd(daemons): """Reload and start system daemons. Args: None Returns: None """ # Say what we are doing print('Checking if daemons are already running') # Loop through daemon list for daemon in daemons: command = '''\ systemctl is-active {} daemon --quiet service-name'''.format(daemon) # Check status code of daemon status = shared.run_script(command, die=False)[0] if status == 0: print(''' {} daemon is already enabled/running, stopping daemon'''.format(daemon)) shared.run_script('systemctl stop {}'.format(daemon)) # Reloading daemons shared.run_script('systemctl daemon-reload') # Enabling daemon shared.run_script('systemctl enable {}'.format(daemon)) # Starting daemon shared.run_script('systemctl start {}'.format(daemon))
def copy_config(file_path, config_dir, container_name): """Copy configuration file from host machine into docker. Args: file_path: The path of the config file being copied config_dir: The configuration directory on the docker container Returns: None """ command = 'docker cp {0} {1}:{2}'.format(file_path, container_name, config_dir) shared.run_script(command)
def docker_check(): """Check if docker is installed/running. Args: None Returns: None """ status = shared.run_script('service docker status', verbose=False, die=False)[0] if status == 0: return True elif status == 3: message = '''\ The docker daemon is not running. Ensure that the docker daemon is running before installing.''' elif status == 4: message = '''\ Docker has not been installed to the system. Ensure that docker is installed before creating the pattoo docker container.''' else: message = '''\ Unknown error code. Ensure that docker is running and has the adequate permissions''' log.log2die_safe(20172, message)
def create_user(): """Create pattoo user and pattoo group. Args: None Returns: None """ # If the group pattoo does not exist, it gets created if not group_exists('pattoo'): print('Creating pattoo group') shared.run_script('groupadd pattoo') # If the user pattoo does not exist, it gets created if not user_exists('pattoo'): print('Creating pattoo user') shared.run_script( 'useradd -d /nonexistent -s /bin/false -g pattoo pattoo')
def venv_check(): """Check if "virtualenv" is installed. If virtualenv is not installed it gets automatically installed to the user's default python path Args: None Returns: None """ # Check if virtualenv is installed try: import virtualenv except ModuleNotFoundError: print('virtualenv is not installed, installing virtualenv') shared.run_script('pip3 install virtualenv==20.0.30')
def pattoo_shared_check(): """Check if pattoo shared is installed. If pattoo shared is not installed, it gets installed to the user's default python path Args: None Returns: None """ # Try except to install pattoo shared try: import pattoo_shared except ModuleNotFoundError: print('PattooShared is missing, installing the latest version') shared.run_script('pip3 install PattooShared')
def image_check(image_name): """Check if a docker image already exists for the image specified. Args: The name of the image being checked Returns: None """ status = shared.run_script('docker image inspect {}'.format(image_name), die=False)[0] if status == 0: message = 'The docker image "{}" already exists'.format(image_name) log.log2die_safe(20170, message)
def install(container_name, config_files, verbose=True): """Perform docker installation for the respective pattoo component. Args: component_name: The name of the pattoo component being dockerized config_files: A list of configuration files file_path: The filepath to the Dockerfile Returns: None """ # Initialize key variables config_dir = os.environ.get('PATTOO_CONFIGDIR') # Insert ports based on config file server_path = os.path.join(config_dir, config_files[1]) expose_ports(server_path, './Dockerfile') # Check if docker is installed/running docker_check() # Build pattoo container image_check('pattoo') print('Building Pattoo Container. This could take some time...') shared.run_script('docker build -t {} .'.format(container_name)) # Run container in detached mode as pattoo run_command = '''\ docker run --privileged -d --network=host --name={0} {0}'''.format( container_name) shared.run_script(run_command, verbose=verbose) # Copy configuration files from host machine for config_file in config_files: file_path = os.path.join(config_dir, config_file) copy_config(file_path, config_dir, container_name) # Run docker installation install_command = '''\ docker exec -i {} setup/install.py install all'''.format(container_name) shared.run_script(install_command)
Args: None Returns: True: If conditions for installation are satisfied """ if getpass.getuser() != 'travis': if getpass.getuser() != 'root': shared.log('You are currently not running the script as root.\ Run as root to continue') return True if __name__ == '__main__': check_user() # Try except to import pattoo libraries if pattoo shared isn't installed try: from _pattoo import packages, systemd, configure except ModuleNotFoundError: default_pip_dir = '/opt/pattoo-daemon/.python' print('Pattoo shared is missing. Installing pattoo shared') shared.run_script('python3 -m pip install PattooShared -t {}'.format( default_pip_dir)) sys.path.append(default_pip_dir) from _pattoo import packages, systemd, configure # Execute main main()
packages.install(ROOT_DIR, venv_dir, args.verbose) # Sets up the configuration for pattoo elif args.qualifier == 'configuration': configure.install(pattoo_home) # Print help if no argument options were triggered else: parser.print_help(sys.stderr) sys.exit(1) # Done print('Done') if __name__ == '__main__': # Ensure environment is okay installation_checks() try: import pattoo_shared except ModuleNotFoundError: shared.run_script('pip3 install PattooShared') # Import packages that depend on pattoo shared from _pattoo import configure from pattoo_shared.installation import packages, systemd, environment # Execute main main()
def install(requirements_dir, installation_directory=None, verbose=True): """Ensure PIP3 packages are installed correctly. Args: requirements_dir: The directory with the pip_requirements file. installation_directory: Directory where packages must be installed. verbose: Print status messages if True Returns: True if pip3 packages are installed successfully """ # Initialize key variables lines = [] if bool(installation_directory) is False: installation_directory = '/opt/pattoo-daemon/.python' # Create directory if it doesn't exist if os.path.isdir(installation_directory) is False: files.mkdir(installation_directory) # Appends pip3 dir to python path sys.path.append(installation_directory) # Read pip_requirements file filepath = '{}{}pip_requirements.txt'.format(requirements_dir, os.sep) # Say what we are doing print('Checking pip3 packages') if os.path.isfile(filepath) is False: shared.log('Cannot find PIP3 requirements file {}'.format(filepath)) # Opens pip_requirements file for reading with open(filepath, 'r') as _fp: line = _fp.readline() while line: # Strip line _line = line.strip() # Read line if True in [_line.startswith('#'), bool(_line) is False]: pass else: lines.append(_line) line = _fp.readline() # Process each line of the file for line in lines: # Determine the package package = line.split('=', 1)[0] package = package.split('>', 1)[0] # If verbose is true, the package being checked is shown if verbose: print('Installing package {}'.format(package)) command = 'python3 -m pip show {}'.format(package) (returncode, _, _) = shared.run_script( command, verbose=verbose, die=False) # Install any missing pip3 package if bool(returncode) is True: install_missing_pip3( package, installation_directory, verbose=verbose) # Set ownership of any newly installed python packages to pattoo user if getpass.getuser() == 'root': if os.path.isdir(installation_directory) is True: shared.run_script('chown -R pattoo:pattoo {}'.format( installation_directory), verbose=verbose) print('pip3 packages successfully installed')