예제 #1
0
파일: reference.py 프로젝트: helium876/mdl
    def populate(self, data_in):
        """Populate data for agent to eventually send to server.

        Args:
            data_in: dict of datapoint values from agent
            timeseries: TimeSeries data if True

        Returns:
            None

        """
        # Initialize data
        data = deepcopy(data_in)

        # Validate base_type
        if len(data) != 1 or isinstance(data, defaultdict) is False:
            log_message = ('Agent data "%s" is invalid') % (data)
            log.log2die(1005, log_message)

        ######################################################################
        # Get a description to use for label value. You could do a lookup in
        # a table based on the spoken language of the environment based on the
        # label and assign the translated result to data[label]['description']
        ######################################################################
        for label in data.keys():
            data[label]['description'] = label
            break

        # Add data to appropriate self.data key
        if data[label]['base_type'] is not None:
            self.data['timeseries'].update(data)
        else:
            self.data['timefixed'].update(data)
예제 #2
0
    def commit(self, session, error_code):
        """Do a database modification.

        Args:
            session: Session
            error_code: Error number to use if one occurs

        Returns:
            None

        """
        # Do commit
        try:
            # Commit  change
            session.commit()

        except Exception as exception_error:
            session.rollback()
            log_message = ('Unable to modify database connection. '
                           'Error: \"%s\"') % (exception_error)
            log.log2die(error_code, log_message)
        except:
            session.rollback()
            log_message = ('Unexpected database exception')
            log.log2die(error_code, log_message)

        # disconnect from server
        self.close()
예제 #3
0
    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: "%s" '
                           'in configuration doesn\'t exist!') % (value)
            log.log2die(1030, log_message)

        # Return
        return value
예제 #4
0
    def add(self, record, error_code):
        """Add a record to the database.

        Args:
            record: Record object
            error_code: Error number to use if one occurs

        Returns:
            None

        """
        # Initialize key variables
        session = self.session()

        # Do add
        try:
            # Commit change
            session.add(record)
            session.commit()

        except Exception as exception_error:
            session.rollback()
            log_message = ('Unable to modify database connection. '
                           'Error: \"%s\"') % (exception_error)
            log.log2die(error_code, log_message)
        except:
            session.rollback()
            log_message = ('Unexpected database exception')
            log.log2die(error_code, log_message)

        # disconnect from server
        self.close()
예제 #5
0
파일: daemon.py 프로젝트: helium876/mdl
    def start(self):
        """Start the daemon.

        Args:
            None

        Returns:

        """
        # Check for a pidfile to see if the daemon already runs
        try:
            with open(self.pidfile, 'r') as pf_handle:
                pid = int(pf_handle.read().strip())

        except IOError:
            pid = None

        if pid:
            log_message = (
                'PID file: %s already exists. Daemon already running?'
                '') % (self.pidfile)
            log.log2die(1062, log_message)

        # Start the daemon
        self.daemonize()

        # Log success
        log_message = ('Daemon Started - PID file: %s') % (self.pidfile)
        log.log2info(1070, log_message)

        # Run code for daemon
        self.run()
예제 #6
0
파일: daemon.py 프로젝트: helium876/mdl
    def stop(self):
        """Stop the daemon.

        Args:
            None

        Returns:

        """
        # Get the pid from the pidfile
        try:
            with open(self.pidfile, 'r') as pf_handle:
                pid = int(pf_handle.read().strip())
        except IOError:
            pid = None

        if not pid:
            log_message = (
                'PID file: %s does not exist. Daemon not running?'
                '') % (self.pidfile)
            log.log2warning(1063, log_message)
            # Not an error in a restart
            return

        # Try killing the daemon process
        try:
            while 1:
                # Sleep a while
                time.sleep(0.3)

                # Process lockfile state when trying to stop
                if self.lockfile is None:
                    os.kill(pid, signal.SIGTERM)
                else:
                    if os.path.exists(self.lockfile) is True:
                        continue
                    else:
                        os.kill(pid, signal.SIGTERM)
        except OSError as err:
            error = str(err.args)
            if error.find("No such process") > 0:
                self.delpid()
                self.dellock()
            else:
                log_message = (str(err.args))
                log_message = (
                    '%s - PID file: %s') % (log_message, self.pidfile)
                log.log2die(1068, log_message)
        except:
            log_message = (
                'Unknown daemon "stop" error for PID file: %s'
                '') % (self.pidfile)
            log.log2die(1066, log_message)

        # Log success
        self.delpid()
        self.dellock()
        log_message = ('Daemon Stopped - PID file: %s') % (self.pidfile)
        log.log2info(1071, log_message)
예제 #7
0
 def validate(self):
     """Make sure we are using a test database."""
     # Only work on test databases
     if self.config.db_name().startswith('test_') is False:
         log_message = ('Test database not found in configuration. '
                        'Try setting your "MDL_CONFIGDIR" environment '
                        'variable to a directory with a test configuration')
         log.log2die(1017, log_message)
예제 #8
0
파일: daemon.py 프로젝트: helium876/mdl
    def daemonize(self):
        """Deamonize class. UNIX double fork mechanism.

        Args:
            None

        Returns:
            None

        """
        # Create a parent process that will manage the child
        # when the code using this class is done.
        try:
            pid = os.fork()
            if pid > 0:
                # Exit first parent
                sys.exit(0)
        except OSError as err:
            log_message = ('Daemon fork #1 failed: %s') % (err)
            log_message = ('%s - PID file: %s') % (log_message, self.pidfile)
            log.log2die(1060, log_message)

        # Decouple from parent environment
        os.chdir('/')
        os.setsid()
        os.umask(0)

        # Do second fork
        try:
            pid = os.fork()
            if pid > 0:

                # exit from second parent
                sys.exit(0)
        except OSError as err:
            log_message = ('Daemon fork #2 failed: %s') % (err)
            log_message = ('%s - PID file: %s') % (log_message, self.pidfile)
            log.log2die(1061, log_message)

        # Redirect standard file descriptors
        sys.stdout.flush()
        sys.stderr.flush()
        f_handle_si = open(os.devnull, 'r')
        # f_handle_so = open(os.devnull, 'a+')
        f_handle_so = open(os.devnull, 'a+')
        f_handle_se = open(os.devnull, 'a+')

        os.dup2(f_handle_si.fileno(), sys.stdin.fileno())
        # os.dup2(f_handle_so.fileno(), sys.stdout.fileno())
        os.dup2(f_handle_so.fileno(), sys.stdout.fileno())
        os.dup2(f_handle_se.fileno(), sys.stderr.fileno())

        # write pidfile
        atexit.register(self.delpid)
        pid = str(os.getpid())
        with open(self.pidfile, 'w+') as f_handle:
            f_handle.write(pid + '\n')
예제 #9
0
파일: reference.py 프로젝트: helium876/mdl
    def purge(self):
        """Purge data from cache by posting to central server.

        Args:
            None

        Returns:
            success: "True: if successful

        """
        # Initialize key variables
        id_agent = self.data['id_agent']

        # Add files in cache directory to list only if they match the
        # cache suffix
        all_filenames = [
            filename for filename in os.listdir(self.cache_dir)
            if os.path.isfile(os.path.join(self.cache_dir, filename))
        ]
        filenames = [
            filename for filename in all_filenames
            if filename.endswith(self.cache_suffix)
        ]

        # Read cache file in sorted order.
        # NOTE: We must post data in timestamp sorted order.
        for filename in filenames.sorted():
            # Only post files for our own UID value
            if id_agent not in filename:
                continue

            # Get the full filepath for the cache file and post
            filepath = os.path.join(self.cache_dir, filename)
            with open(filepath, 'r') as f_handle:
                try:
                    data = json.load(f_handle)
                except:
                    # Log removal
                    log_message = (
                        'Error reading previously cached agent data file %s '
                        'for agent %s. May be corrupted.'
                        '') % (filepath, self.name())
                    log.log2die(1058, log_message)

            # Post file
            success = self.post(save=False, data=data)

            # Delete file if successful
            if success is True:
                os.remove(filepath)

                # Log removal
                log_message = ('Purging cache file %s after successfully '
                               'contacting server'
                               '') % (filepath)
                log.log2info(1053, log_message)
예제 #10
0
    def add_all(self, data_list, error_code, die=True):
        """Do a database modification.

        Args:
            data_list: List of sqlalchemy table objects
            error_code: Error number to use if one occurs
            die: Don't die if False, just return success

        Returns:
            success: True is successful

        """
        # Initialize key variables
        success = False

        # Open database connection. Prepare cursor
        session = self.session()

        try:
            # Update the database cache
            session.add_all(data_list)

            # Commit  change
            session.commit()

            # disconnect from server
            self.close()

            # Update success
            success = True

        except Exception as exception_error:
            success = False
            session.rollback()
            log_message = ('Unable to modify database connection. '
                           'Error: \"%s\"') % (exception_error)
            if die is True:
                log.log2die(error_code, log_message)
            else:
                log.log2warning(error_code, log_message)

        except:
            success = False
            session.rollback()
            log_message = ('Unexpected database exception')
            if die is True:
                log.log2die(error_code, log_message)
            else:
                log.log2warning(error_code, log_message)

        # Return
        return success
예제 #11
0
파일: setup.py 프로젝트: helium876/mdl
    def setup(self):
        """Setup database.

        Args:
            None

        Returns:
            None

        """
        # Initialize key variables
        use_mysql = True
        pool_size = 25
        max_overflow = 25
        config = self.config

        # Create DB connection pool
        if use_mysql is True:
            # Add MySQL to the pool
            engine = create_engine(URL,
                                   echo=True,
                                   encoding='utf8',
                                   max_overflow=max_overflow,
                                   pool_size=pool_size,
                                   pool_recycle=3600)

            # Try to create the database
            print_ok('Attempting to create database tables')
            try:
                sql_string = ('ALTER DATABASE %s CHARACTER SET utf8mb4 '
                              'COLLATE utf8mb4_general_ci') % (
                                  config.db_name())
                engine.execute(sql_string)
            except:
                log_message = (
                    'Cannot connect to database %s. '
                    'Verify database server is started. '
                    'Verify database is created. '
                    'Verify that the configured database authentication '
                    'is correct.') % (config.db_name())
                log.log2die(1036, log_message)

            # Apply schemas
            print_ok('Applying Schemas')
            BASE.metadata.create_all(engine)
예제 #12
0
파일: daemon.py 프로젝트: helium876/mdl
def _mkdir(directory):
    """Create a directory if it doesn't already exist.

    Args:
        directory: Directory name

    Returns:
        None

    """
    # Do work
    if os.path.exists(directory) is False:
        os.makedirs(directory, mode=0o755)
    else:
        if os.path.isfile(directory) is True:
            log_message = (
                '%s is not a directory.'
                '') % (directory)
            log.log2die(1043, log_message)
예제 #13
0
파일: general.py 프로젝트: helium876/mdl
def run_script(cli_string, shell=False, die=True):
    """Run the cli_string UNIX CLI command and record output.

    Args:
        cli_string: Command to run on the CLI
        die: Die if command runs with an error

    Returns:
        None

    """
    # Initialize key variables
    encoding = locale.getdefaultlocale()[1]
    header_returncode = ('[Return Code]')
    header_stdout = ('[Output]')
    header_stderr = ('[Error Message]')
    header_bad_cmd = ('[ERROR: Bad Command]')
    log_message = ''

    # Create the subprocess object
    if shell is False:
        do_command_list = list(cli_string.split(' '))
        process = subprocess.Popen(do_command_list,
                                   shell=False,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
    else:
        process = subprocess.Popen(cli_string,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
    stdoutdata, stderrdata = process.communicate()
    returncode = process.returncode

    # Crash if the return code is not 0
    if die is True:
        if returncode != 0:
            # Print the Return Code header, Return Code, STDOUT header
            string2print = ('%s %s %s %s') % (header_bad_cmd, cli_string,
                                              header_returncode, returncode)
            log_message = ('%s%s') % (log_message, string2print)

            # Print the STDERR
            string2print = ('%s') % (header_stderr)
            log_message = ('%s %s') % (log_message, string2print)
            for line in stderrdata.decode(encoding).split('\n'):
                string2print = ('%s') % (line)
                log_message = ('%s %s') % (log_message, string2print)

            # Print the STDOUT
            string2print = ('%s') % (header_stdout)
            log_message = ('%s %s') % (log_message, string2print)
            for line in stdoutdata.decode(encoding).split('\n'):
                string2print = ('%s') % (line)
                log_message = ('%s %s') % (log_message, string2print)

            # All done
            log.log2die(1074, log_message)

    # Return
    return stdoutdata