Example #1
0
    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: {} already exists. Daemon already running?'
                ''.format(self.pidfile))
            log.log2die(1062, log_message)

        # Start the daemon
        self.daemonize()

        # Log success
        log_message = ('Daemon {} started - PID file: {}'
                       ''.format(self.name, self.pidfile))
        log.log2info(1070, log_message)

        # Run code for daemon
        self.run()
Example #2
0
    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 "{}" is invalid'.format(data)
            log.log2die(1025, log_message)

        # Get a description to use for label value
        for label in data.keys():
            description = self._lang.label_description(label)
            data[label]['description'] = description
            break

        # Add data to appropriate self._data key
        if data[label]['base_type'] is not None:
            self._data['devices'][self._devicename]['timeseries'].update(data)
        else:
            self._data['devices'][self._devicename]['timefixed'].update(data)
Example #3
0
def _ip_binding():
    """Create IPv4 / IPv6 binding for Gunicorn.

    Args:
        None

    Returns:
        result: bind

    """
    # Initialize key variables
    config = CONFIG
    ipv4 = False
    ip_address = config.listen_address()

    # Check IP address type
    try:
        ip_object = ipaddress.ip_address(ip_address)
    except:
        log_message = (
            'The {} IP address in the configuration file is incorrectly '
            'formatted'.format(ip_address))
        log.log2die(1234, log_message)

    # Is this an IPv4 address?
    ipv4 = isinstance(ip_object, ipaddress.IPv4Address)
    if ipv4 is True:
        result = '{}:{}'.format(ip_address, config.bind_port())
    else:
        result = '[{}]:{}'.format(ip_address, config.bind_port())

    return result
Example #4
0
    def agent_cache_directory(self):
        """Determine the agent_cache_directory.

        Args:
            None

        Returns:
            value: configured agent_cache_directory

        """
        # Initialize key variables
        key = 'main'
        sub_key = 'agent_cache_directory'

        # Get result
        _value = _key_sub_key(key, sub_key, self._config_dict)

        # Expand linux ~ notation for home directories if provided.
        value = os.path.expanduser(_value)

        # Check if value exists
        if os.path.isdir(value) is False:
            log_message = ('agent_cache_directory: "{}" '
                           'in configuration doesn\'t exist!'.format(value))
            log.log2die(1031, log_message)

        # Return
        return value
Example #5
0
    def log_directory(self):
        """Get log_directory.

        Args:
            None

        Returns:
            result: result

        """
        # Get result
        sub_key = 'log_directory'
        result = None
        key = 'main'

        # Get new result
        _result = _key_sub_key(key, sub_key, self._config_dict)

        # Expand linux ~ notation for home directories if provided.
        result = os.path.expanduser(_result)

        # Check if value exists
        if os.path.isdir(result) is False:
            log_message = ('log_directory: "{}" '
                           'in configuration doesn\'t exist!'.format(result))
            log.log2die(1010, log_message)

        # Return
        return result
Example #6
0
    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: {} does not exist. Daemon not running?'
                           ''.format(self.pidfile))
            log.log2warning(1063, log_message)
            # Not an error in a restart
            return

        # Try killing the daemon process
        try:
            while 1:
                if self.lockfile is None:
                    os.kill(pid, signal.SIGTERM)
                else:
                    time.sleep(0.3)
                    if os.path.exists(self.lockfile) is True:
                        continue
                    else:
                        os.kill(pid, signal.SIGTERM)
                time.sleep(0.3)
        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 = ('{} - PID file: {}'.format(
                    log_message, self.pidfile))
                log.log2die(1068, log_message)
        except:
            log_message = ('Unknown daemon "stop" error for PID file: {}'
                           ''.format(self.pidfile))
            log.log2die(1066, log_message)

        # Log success
        self.delpid()
        self.dellock()
        log_message = ('Daemon {} stopped - PID file: {}'
                       ''.format(self.name, self.pidfile))
        log.log2info(1071, log_message)
Example #7
0
    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: {}'.format(err)
            log_message = '{} - PID file: {}'.format(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: {}'.format(err)
            log_message = '{} - PID file: {}'.format(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_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_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')
Example #8
0
    def purge(self):
        """Purge data from cache by posting to central server.

        Args:
            None

        Returns:
            success: "True: if successful

        """
        # Initialize key variables
        agent_id = self._data['agent_id']

        # 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_filename_suffix)
        ]

        # Read cache file
        for filename in filenames:
            # Only post files for our own UID value
            if agent_id 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 {} '
                        'for agent {}. May be corrupted.'
                        ''.format(filepath, self._agent_name))
                    log.log2die(1064, 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 {} after successfully '
                               'contacting server {}'
                               ''.format(filepath, self._url))
                log.log2info(1029, log_message)
Example #9
0
def read_yaml_files(config_directory):
    """Read the contents of all yaml files in a directory.

    Args:
        config_directory: Directory with configuration files

    Returns:
        config_dict: Dict of yaml read

    """
    # Initialize key variables
    yaml_found = False
    yaml_from_file = ''
    all_yaml_read = ''

    if os.path.isdir(config_directory) is False:
        log_message = ('Configuration directory "{}" '
                       'doesn\'t exist!'.format(config_directory))
        log.log2die(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'):
            # YAML files found
            yaml_found = True

            # Read file and add to string
            file_path = '{}/{}'.format(config_directory, filename)
            try:
                with open(file_path, 'r') as file_handle:
                    yaml_from_file = file_handle.read()
            except:
                log_message = ('Error reading file {}. Check permissions, '
                               'existence and file syntax.'
                               ''.format(file_path))
                log.log2die(1065, log_message)

            # Append yaml from file to all yaml previously read
            all_yaml_read = '{}\n{}'.format(all_yaml_read, yaml_from_file)

    # Verify YAML files found in directory. We cannot use logging as it
    # requires a logfile location from the configuration directory to work
    # properly
    if yaml_found is False:
        log_message = (
            'No configuration files found in directory "{}" with ".yaml" '
            'extension.'.format(config_directory))
        print(log_message)
        sys.exit(1)

    # Return
    config_dict = yaml.safe_load(all_yaml_read)
    return config_dict
Example #10
0
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=0o775)
    else:
        if os.path.isfile(directory) is True:
            log_message = ('{} is not a directory.' ''.format(directory))
            log.log2die(1043, log_message)
Example #11
0
    def agents(self):
        """Get agents.

        Args:
            None

        Returns:
            result: list of agents

        """
        # Initialize key variables
        key = 'agents'
        result = None

        # Verify data
        if key not in self._config_dict:
            log_message = ('No agents configured')
            log.log2die(1100, log_message)

        # Process agents
        result = self._config_dict[key]

        # Return
        return result