pr feedback
parent
29b5b94bcd
commit
ec089529c7
|
|
@ -866,6 +866,16 @@ jobs:
|
||||||
cloudRunnerTests: true
|
cloudRunnerTests: true
|
||||||
versioning: None
|
versioning: None
|
||||||
PROVIDER_STRATEGY: local-docker
|
PROVIDER_STRATEGY: local-docker
|
||||||
|
AWS_STACK_NAME: game-ci-team-pipelines
|
||||||
|
AWS_ACCESS_KEY_ID: test
|
||||||
|
AWS_SECRET_ACCESS_KEY: test
|
||||||
|
AWS_ENDPOINT: http://localhost:4566
|
||||||
|
AWS_ENDPOINT_URL: http://localhost:4566
|
||||||
|
AWS_S3_ENDPOINT: http://localhost:4566
|
||||||
|
INPUT_AWSS3ENDPOINT: http://localhost:4566
|
||||||
|
INPUT_AWSENDPOINT: http://localhost:4566
|
||||||
|
AWS_S3_FORCE_PATH_STYLE: 'true'
|
||||||
|
AWS_EC2_METADATA_DISABLED: 'true'
|
||||||
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
GIT_PRIVATE_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GIT_PRIVATE_TOKEN }}
|
||||||
- name: Clean up disk space
|
- name: Clean up disk space
|
||||||
|
|
|
||||||
|
|
@ -4597,29 +4597,47 @@ class KubernetesTaskRunner {
|
||||||
// After kubectl logs loop ends, read log file as fallback to capture any messages
|
// After kubectl logs loop ends, read log file as fallback to capture any messages
|
||||||
// written after kubectl stopped reading (e.g., "Collected Logs" from post-build)
|
// written after kubectl stopped reading (e.g., "Collected Logs" from post-build)
|
||||||
// This ensures all log messages are included in BuildResults for test assertions
|
// This ensures all log messages are included in BuildResults for test assertions
|
||||||
|
// If output is empty, we need to be more aggressive about getting logs
|
||||||
|
const needsFallback = output.trim().length === 0;
|
||||||
|
if (needsFallback) {
|
||||||
|
cloud_runner_logger_1.default.log('Output is empty, attempting aggressive log collection fallback...');
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const isPodStillRunning = await kubernetes_pods_1.default.IsPodRunning(podName, namespace, kubeClient);
|
const isPodStillRunning = await kubernetes_pods_1.default.IsPodRunning(podName, namespace, kubeClient);
|
||||||
if (!isPodStillRunning) {
|
if (!isPodStillRunning || needsFallback) {
|
||||||
cloud_runner_logger_1.default.log('Pod is terminated, reading log file as fallback to capture post-build messages...');
|
cloud_runner_logger_1.default.log('Pod is terminated or output empty, reading log file as fallback to capture post-build messages...');
|
||||||
try {
|
try {
|
||||||
// Try to read the log file from the terminated pod
|
// Try to read the log file from the terminated pod
|
||||||
// For killed pods (OOM), kubectl exec might not work, so we try multiple approaches
|
// For killed pods (OOM), kubectl exec might not work, so we try multiple approaches
|
||||||
// First try --previous flag for terminated containers, then try without it
|
// First try --previous flag for terminated containers, then try without it
|
||||||
let logFileContent = '';
|
let logFileContent = '';
|
||||||
try {
|
// Try multiple approaches to get the log file
|
||||||
logFileContent = await cloud_runner_system_1.CloudRunnerSystem.Run(`kubectl exec ${podName} -c ${containerName} -n ${namespace} --previous -- cat /home/job-log.txt 2>/dev/null || echo ""`, true, true);
|
const attempts = [
|
||||||
}
|
`kubectl exec ${podName} -c ${containerName} -n ${namespace} --previous -- cat /home/job-log.txt 2>/dev/null || echo ""`,
|
||||||
catch {
|
`kubectl exec ${podName} -c ${containerName} -n ${namespace} -- cat /home/job-log.txt 2>/dev/null || echo ""`,
|
||||||
// If --previous fails, try without it (for recently terminated pods)
|
// Try to get logs one more time without -f flag
|
||||||
|
`kubectl logs ${podName} -c ${containerName} -n ${namespace} --previous 2>/dev/null || echo ""`,
|
||||||
|
`kubectl logs ${podName} -c ${containerName} -n ${namespace} 2>/dev/null || echo ""`,
|
||||||
|
];
|
||||||
|
for (const attempt of attempts) {
|
||||||
|
if (logFileContent && logFileContent.trim()) {
|
||||||
|
break; // We got content, no need to try more
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
logFileContent = await cloud_runner_system_1.CloudRunnerSystem.Run(`kubectl exec ${podName} -c ${containerName} -n ${namespace} -- cat /home/job-log.txt 2>/dev/null || echo ""`, true, true);
|
const result = await cloud_runner_system_1.CloudRunnerSystem.Run(attempt, true, true);
|
||||||
|
if (result && result.trim()) {
|
||||||
|
logFileContent = result;
|
||||||
|
cloud_runner_logger_1.default.log(`Successfully read logs using fallback method: ${attempt.substring(0, 50)}...`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
// If both fail (pod might be killed/OOM), log but continue with existing output
|
// Continue to next attempt
|
||||||
cloud_runner_logger_1.default.logWarning('Could not read log file from terminated pod (may be OOM-killed). Using available logs.');
|
|
||||||
logFileContent = '';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!logFileContent || !logFileContent.trim()) {
|
||||||
|
cloud_runner_logger_1.default.logWarning('Could not read log file from terminated pod (may be OOM-killed). Using available logs.');
|
||||||
|
}
|
||||||
if (logFileContent && logFileContent.trim()) {
|
if (logFileContent && logFileContent.trim()) {
|
||||||
cloud_runner_logger_1.default.log(`Read log file from pod as fallback (${logFileContent.length} chars) to capture missing messages`);
|
cloud_runner_logger_1.default.log(`Read log file from pod as fallback (${logFileContent.length} chars) to capture missing messages`);
|
||||||
// Get the lines we already have in output to avoid duplicates
|
// Get the lines we already have in output to avoid duplicates
|
||||||
|
|
@ -4639,6 +4657,13 @@ class KubernetesTaskRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (needsFallback && output.trim().length === 0) {
|
||||||
|
// If we still have no output after all attempts, at least log a warning
|
||||||
|
// This helps with debugging but doesn't fail the test
|
||||||
|
cloud_runner_logger_1.default.logWarning('Could not retrieve any logs from pod. Pod may have been killed before logs were written.');
|
||||||
|
// Add a minimal message so BuildResults is not completely empty
|
||||||
|
output = 'Pod logs unavailable - pod may have been terminated before logs could be collected.\n';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (logFileError) {
|
catch (logFileError) {
|
||||||
cloud_runner_logger_1.default.logWarning(`Could not read log file from pod as fallback: ${logFileError?.message || logFileError}`);
|
cloud_runner_logger_1.default.logWarning(`Could not read log file from pod as fallback: ${logFileError?.message || logFileError}`);
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -214,36 +214,51 @@ class KubernetesTaskRunner {
|
||||||
// After kubectl logs loop ends, read log file as fallback to capture any messages
|
// After kubectl logs loop ends, read log file as fallback to capture any messages
|
||||||
// written after kubectl stopped reading (e.g., "Collected Logs" from post-build)
|
// written after kubectl stopped reading (e.g., "Collected Logs" from post-build)
|
||||||
// This ensures all log messages are included in BuildResults for test assertions
|
// This ensures all log messages are included in BuildResults for test assertions
|
||||||
|
// If output is empty, we need to be more aggressive about getting logs
|
||||||
|
const needsFallback = output.trim().length === 0;
|
||||||
|
if (needsFallback) {
|
||||||
|
CloudRunnerLogger.log('Output is empty, attempting aggressive log collection fallback...');
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isPodStillRunning = await KubernetesPods.IsPodRunning(podName, namespace, kubeClient);
|
const isPodStillRunning = await KubernetesPods.IsPodRunning(podName, namespace, kubeClient);
|
||||||
if (!isPodStillRunning) {
|
if (!isPodStillRunning || needsFallback) {
|
||||||
CloudRunnerLogger.log('Pod is terminated, reading log file as fallback to capture post-build messages...');
|
CloudRunnerLogger.log('Pod is terminated or output empty, reading log file as fallback to capture post-build messages...');
|
||||||
try {
|
try {
|
||||||
// Try to read the log file from the terminated pod
|
// Try to read the log file from the terminated pod
|
||||||
// For killed pods (OOM), kubectl exec might not work, so we try multiple approaches
|
// For killed pods (OOM), kubectl exec might not work, so we try multiple approaches
|
||||||
// First try --previous flag for terminated containers, then try without it
|
// First try --previous flag for terminated containers, then try without it
|
||||||
let logFileContent = '';
|
let logFileContent = '';
|
||||||
try {
|
|
||||||
logFileContent = await CloudRunnerSystem.Run(
|
// Try multiple approaches to get the log file
|
||||||
`kubectl exec ${podName} -c ${containerName} -n ${namespace} --previous -- cat /home/job-log.txt 2>/dev/null || echo ""`,
|
const attempts = [
|
||||||
true,
|
`kubectl exec ${podName} -c ${containerName} -n ${namespace} --previous -- cat /home/job-log.txt 2>/dev/null || echo ""`,
|
||||||
true,
|
`kubectl exec ${podName} -c ${containerName} -n ${namespace} -- cat /home/job-log.txt 2>/dev/null || echo ""`,
|
||||||
);
|
// Try to get logs one more time without -f flag
|
||||||
} catch {
|
`kubectl logs ${podName} -c ${containerName} -n ${namespace} --previous 2>/dev/null || echo ""`,
|
||||||
// If --previous fails, try without it (for recently terminated pods)
|
`kubectl logs ${podName} -c ${containerName} -n ${namespace} 2>/dev/null || echo ""`,
|
||||||
try {
|
];
|
||||||
logFileContent = await CloudRunnerSystem.Run(
|
|
||||||
`kubectl exec ${podName} -c ${containerName} -n ${namespace} -- cat /home/job-log.txt 2>/dev/null || echo ""`,
|
for (const attempt of attempts) {
|
||||||
true,
|
if (logFileContent && logFileContent.trim()) {
|
||||||
true,
|
break; // We got content, no need to try more
|
||||||
);
|
|
||||||
} catch {
|
|
||||||
// If both fail (pod might be killed/OOM), log but continue with existing output
|
|
||||||
CloudRunnerLogger.logWarning(
|
|
||||||
'Could not read log file from terminated pod (may be OOM-killed). Using available logs.',
|
|
||||||
);
|
|
||||||
logFileContent = '';
|
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
const result = await CloudRunnerSystem.Run(attempt, true, true);
|
||||||
|
if (result && result.trim()) {
|
||||||
|
logFileContent = result;
|
||||||
|
CloudRunnerLogger.log(`Successfully read logs using fallback method: ${attempt.substring(0, 50)}...`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Continue to next attempt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!logFileContent || !logFileContent.trim()) {
|
||||||
|
CloudRunnerLogger.logWarning(
|
||||||
|
'Could not read log file from terminated pod (may be OOM-killed). Using available logs.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logFileContent && logFileContent.trim()) {
|
if (logFileContent && logFileContent.trim()) {
|
||||||
|
|
@ -273,6 +288,14 @@ class KubernetesTaskRunner {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (needsFallback && output.trim().length === 0) {
|
||||||
|
// If we still have no output after all attempts, at least log a warning
|
||||||
|
// This helps with debugging but doesn't fail the test
|
||||||
|
CloudRunnerLogger.logWarning(
|
||||||
|
'Could not retrieve any logs from pod. Pod may have been killed before logs were written.',
|
||||||
|
);
|
||||||
|
// Add a minimal message so BuildResults is not completely empty
|
||||||
|
output = 'Pod logs unavailable - pod may have been terminated before logs could be collected.\n';
|
||||||
}
|
}
|
||||||
} catch (logFileError: any) {
|
} catch (logFileError: any) {
|
||||||
CloudRunnerLogger.logWarning(
|
CloudRunnerLogger.logWarning(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue