<commit_before>'''
Madeira OpsAgent state runner

@author: Michael (<EMAIL>)
'''

import os
import json

from salt.state import State

from opsagent import utils
from opsagent.exception import StateException, OpsAgentException

class StateRunner(object):

	def __init__(self, config):

		self.state = None

		# init salt opts
		self._init_opts(config)

		# init state
		self._init_state()

	def _init_opts(self, config):

		self._salt_opts = {
			'file_client':       'local',
			'renderer':          'yaml_jinja',
			'failhard':          False,
			'state_top':         'salt://top.sls',
			'nodegroups':        {},
			'file_roots':        {'base': [ ]},
			'state_auto_order':  False,
			'extension_modules': None,
			'id':                '',
			'pillar_roots':      '',
			'cachedir':          None,
			'test':              False,
		}

		# file roots
		for path in config['file_roots'].split(':'):
			# check and make path
			if not self.__mkdir(path):
				continue

			self._salt_opts['file_roots']['base'].append(path)

		if len(self._salt_opts['file_roots']['base']) == 0:		raise StateException("Missing file roots argument")
		if not self.__mkdir(config['extension_modules']):		raise StateException("Missing extension modules argument")

		self._salt_opts['extension_modules'] = config['extension_modules']

		if not self.__mkdir(config['cachedir']):	raise StateException("Missing cachedir argument")

		self._salt_opts['cachedir'] = config['cachedir']

	def _init_state(self):
		"""
			Init salt state object.
		"""

		self.state = State(self._salt_opts)

	def exec_salt(self, state):
		"""
			Transfer and exec salt state.
			return result format: (result,comment,out_log), result:True/False
		"""

		result = False
		comment = ''
		out_log = ''

		# check
		if not state or not isinstance(state, dict):
			out_log = "invalid state"
			return (result, comment, out_log)

		ret = self.state.call_high(state)
		if ret:
			# parse the ret and return
			utils.log("DEBUG", json.dumps(ret), ("exec_salt", self))

			# set comment and output log
			result = False
			for r_tag, r_value in ret.items():
				if 'comment' in r_value:
					comment += '\n\n' + r_value['comment']
				if 'state_stdout' in r_value:
					out_log += '\n\n' + r_value['state_stdout']
				if 'result' not in r_value:
					continue

				result = r_value['result']
				# break when one state runs failed
				if not result:
					break

		else:
			out_log = "wait failed"

		return (result, comment, out_log)

	def __mkdir(self, path):
		"""
			Check and make directory.
		"""<commit_msg>[develop] adjust result log order<commit_after>'''
Madeira OpsAgent state runner

@author: Michael (<EMAIL>)
'''

import os
import json

from salt.state import State

from opsagent import utils
from opsagent.exception import StateException, OpsAgentException

class StateRunner(object):

	def __init__(self, config):

		self.state = None

		# init salt opts
		self._init_opts(config)

		# init state
		self._init_state()

	def _init_opts(self, config):

		self._salt_opts = {
			'file_client':       'local',
			'renderer':          'yaml_jinja',
			'failhard':          False,
			'state_top':         'salt://top.sls',
			'nodegroups':        {},
			'file_roots':        {'base': [ ]},
			'state_auto_order':  False,
			'extension_modules': None,
			'id':                '',
			'pillar_roots':      '',
			'cachedir':          None,
			'test':              False,
		}

		# file roots
		for path in config['file_roots'].split(':'):
			# check and make path
			if not self.__mkdir(path):
				continue

			self._salt_opts['file_roots']['base'].append(path)

		if len(self._salt_opts['file_roots']['base']) == 0:		raise StateException("Missing file roots argument")
		if not self.__mkdir(config['extension_modules']):		raise StateException("Missing extension modules argument")

		self._salt_opts['extension_modules'] = config['extension_modules']

		if not self.__mkdir(config['cachedir']):	raise StateException("Missing cachedir argument")

		self._salt_opts['cachedir'] = config['cachedir']

	def _init_state(self):
		"""
			Init salt state object.
		"""

		self.state = State(self._salt_opts)

	def exec_salt(self, state):
		"""
			Transfer and exec salt state.
			return result format: (result,comment,out_log), result:True/False
		"""

		result = False
		comment = ''
		out_log = ''

		# check
		if not state or not isinstance(state, dict):
			out_log = "invalid state"
			return (result, comment, out_log)

		ret = self.state.call_high(state)
		if ret:
			# parse the ret and return
			utils.log("DEBUG", json.dumps(ret), ("exec_salt", self))

			# set comment and output log
			result = False
			require_in_comment = ''
			require_in_log = ''
			for r_tag, r_value in ret.items():
				if 'result' not in r_value:	continue 	# filter no result

				# parse require in result
				if 'require_in' in r_tag:
					require_in_comment = '{0}{1}{2}'.format(
							require_in_comment,
							'\n\n' if require_in_comment else '',
							r_value['comment'] if 'comment' in r_value and r_value['comment'] else ''
						)
					require_in_log = '{0}{1}{2}'.format(
							require_in_log,
							'\n\n' if require_in_log else '',
							r_value['state_stdout'] if 'state_stdout' in r_value and r_value['state_stdout'] else ''
						)

				# parse require result
				elif 'require' in r_tag:
					comment = '{0}{1}{2}'.format(
						r_value['comment'] if 'comment' in r_value and r_value['comment'] else '',
						'\n\n' if comment else '',
						comment
						)
					out_log = '{0}{1}{2}'.format(
						r_value['state_stdout'] if 'state_stdout' in r_value and r_value['state_stdout'] else '',
						'\n\n' if out_log else '',
						out_log
						)

				# parse common result
				else:
					comment = '{0}{1}{2}'.format(
						comment,
						'\n\n' if comment else '',
						r_value['comment'] if 'comment' in r_value and r_value['comment'] else ''
						)
					out_log = '{0}{1}{2}'.format(
						out_log,
						'\n\n' if out_log else '',
						r_value['state_stdout'] if 'state_stdout' in r_value and r_value['state_stdout'] else ''
						)

				result = r_value['result']
				# break when one state runs failed
				if not result:
					break

			# add require in comment and log
			if require_in_comment:
				comment += '\n\n' + require_in_comment

			if require_in_log:
				out_log += '\n\n' + require_in_log

		else:
			out_log = "wait failed"

		return (result, comment, out_log)

	def __mkdir(self, path):
		"""
			Check and make directory.
		"""
{'fraction_non_alphanumeric': 0.13659437009690817, 'fraction_numerical': 0.003076449776957391, 'mean_word_length': 3.0841708542713566, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '500494', 'n_tokens_mistral': 2597, 'n_tokens_neox': 2100, 'n_words': 556}