package ee.elinyo.teamcity.plugins.ansible.agent; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import jetbrains.buildServer.agent.AgentRunningBuild; import jetbrains.buildServer.agent.BuildRunnerContext; import jetbrains.buildServer.agent.artifacts.ArtifactsWatcher; import jetbrains.buildServer.agent.runner.ProcessListener; import com.intellij.openapi.diagnostic.Logger; import ee.elinyo.teamcity.plugins.ansible.common.AnsibleRunnerConstants; import ee.elinyo.teamcity.plugins.ansible.logparser.AnsibleLogUtils; import ee.elinyo.teamcity.plugins.ansible.logparser.DateDecorator; public class AnsibleOutputListener implements ProcessListener { private static final Logger LOG = Logger.getInstance(AnsibleOutputListener.class.getName()); private File rawFile; private PrintWriter rawFileWriter; private final ArtifactsWatcher artifactsWatcher; private final BuildRunnerContext buildRunnerContext; public AnsibleOutputListener(AgentRunningBuild build, BuildRunnerContext buildRunnerContext, ArtifactsWatcher artifactsWatcher) { this.artifactsWatcher = artifactsWatcher; this.buildRunnerContext = buildRunnerContext; File tmpDir = new File(build.getBuildTempDirectory(), "ansible-run"); boolean exists = tmpDir.exists(); if (!exists) { exists = tmpDir.mkdir(); } if (!exists) { LOG.error("Cannot create a directory " + tmpDir.getAbsolutePath() + " for ansible run raw output storage"); build.getBuildLogger().warning("Cannot create a directory for ansible run raw output storage. Ansible report will not be generated"); } else { String rawFileName = "ansible-run-raw-" + buildRunnerContext.getId() + ".log"; rawFile = new File(tmpDir, rawFileName); try { rawFile.createNewFile(); } catch (IOException e) { LOG.error("Cannot create a file " + rawFileName + " for ansible run raw output writing ", e); build.getBuildLogger().warning("Cannot create a file for ansible run raw output writing. Ansible report will not be generated"); } build.addSharedConfigParameter(AnsibleRunnerConstants.ARTIFACTS_TMP_DIR_KEY, tmpDir.getAbsolutePath()); } } @Override public void onStandardOutput(String text) { if (rawFileWriter != null) { rawFileWriter.println(DateDecorator.decorate(text)); } } @Override public void onErrorOutput(String text) { buildRunnerContext.getBuild().getBuildLogger().error(text); onStandardOutput(text); } @Override public void processStarted(String programCommandLine, File workingDirectory) { if (rawFile != null) { try { rawFileWriter = new PrintWriter(rawFile); writeStartMeta(); } catch (FileNotFoundException e) { LOG.error("Cannot find a file for ansible run raw output writing", e); } } } @Override public void processFinished(int exitCode) { if (rawFileWriter != null) { writeEndMeta(exitCode); rawFileWriter.close(); artifactsWatcher.addNewArtifactsPath(rawFile.getAbsolutePath() + "=>" + AnsibleRunnerConstants.ARTIFACTS_BASE_DIR); } } private void writeStartMeta() { String runnerIdMsg = AnsibleLogUtils.getBuildMetaMessage(AnsibleRunnerConstants.RUNNER_ID_META_KEY, buildRunnerContext.getId()); rawFileWriter.println(DateDecorator.decorate(runnerIdMsg)); String stepNameMsg = AnsibleLogUtils.getBuildMetaMessage(AnsibleRunnerConstants.STEP_NAME_META_KEY, buildRunnerContext.getName()); rawFileWriter.println(DateDecorator.decorate(stepNameMsg)); } private void writeEndMeta(int exitCode) { String runnerIdMsg = AnsibleLogUtils.getBuildMetaMessage(AnsibleRunnerConstants.EXIT_CODE_META_KEY, String.valueOf(exitCode)); rawFileWriter.println(DateDecorator.decorate(runnerIdMsg)); } }