-
Notifications
You must be signed in to change notification settings - Fork 94
feat(x2a): Error handling - error from python log #2585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@red-hat-developer-hub/backstage-plugin-x2a-backend': patch | ||
| --- | ||
|
|
||
| Improve error propagation in job script: consolidate error handling into run_x2a function with default message and appended error details, add command logging, and refactor publish-aap to use the shared error handler. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,9 @@ | |
| TERMINATED=false | ||
| COMMIT_ID="" | ||
|
|
||
| # Path where x2a-convertor writes error details on failure | ||
| export X2A_ERROR_FILE="/tmp/x2a-error.txt" | ||
|
|
||
| # Report job result back to the backend. | ||
| report_result() { | ||
| local status="$1" | ||
|
|
@@ -74,6 +77,38 @@ | |
| fi | ||
| } | ||
|
|
||
| # Run an x2a tool command with error reporting. | ||
| # On failure, reads the error details file written by x2a-convertor and sets ERROR_MESSAGE. | ||
| # On success, clears ERROR_MESSAGE. | ||
| # Captured output is stored in X2A_OUTPUT for callers that need to parse it. | ||
| # Usage: run_x2a uv run app.py <phase> [args...] | ||
| run_x2a() { | ||
|
Check warning on line 85 in workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh
|
||
| rm -f "${X2A_ERROR_FILE}" | ||
|
|
||
| echo "Command: $*" | ||
|
|
||
| local tmpfile | ||
| tmpfile=$(mktemp) | ||
|
|
||
| set +e | ||
| "$@" 2>&1 | tee "${tmpfile}" | ||
| local rc=${PIPESTATUS[0]} | ||
| set -e | ||
|
|
||
| X2A_OUTPUT=$(cat "${tmpfile}") | ||
| rm -f "${tmpfile}" | ||
|
|
||
| if [ ${rc} -ne 0 ]; then | ||
|
Check failure on line 101 in workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh
|
||
| ERROR_MESSAGE="Unexpected error during ${PHASE} phase. See the job log for details." | ||
| if [ -f "${X2A_ERROR_FILE}" ]; then | ||
|
Check failure on line 103 in workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh
|
||
| ERROR_MESSAGE+=" Message: $(cat "${X2A_ERROR_FILE}")" | ||
| fi | ||
|
Comment on lines
+103
to
+105
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1. run_x2a fallback lacks exit code When x2a-convertor fails and ${X2A_ERROR_FILE} is missing, the new fallback sets ERROR_MESSAGE
to a generic string instead of the required Script failed with exit code N. This can prevent the
backend from surfacing the mandated fallback errorDetails format.
Agent Prompt
|
||
| exit ${rc} | ||
| fi | ||
|
|
||
| ERROR_MESSAGE="" | ||
| } | ||
|
|
||
| # Cleanup trap: fires on every exit (success or failure). | ||
| # Guarantees exactly one report_result call regardless of how the script ends. | ||
| cleanup() { | ||
|
|
@@ -226,10 +261,7 @@ | |
| # Usage: app.py init [OPTIONS] USER_REQUIREMENTS | ||
| # --source-dir DIRECTORY Source directory to analyze | ||
| USER_REQ="${USER_PROMPT:-Analyze the Chef cookbooks and create a migration plan}" | ||
| echo "Command: uv run app.py init --source-dir ${SOURCE_BASE} \"${USER_REQ}\"" | ||
| ERROR_MESSAGE="Unexpected error during init phase. See the job log for details." | ||
| uv run app.py init --source-dir "${SOURCE_BASE}" "${USER_REQ}" | ||
| ERROR_MESSAGE="" | ||
| run_x2a uv run app.py init --source-dir "${SOURCE_BASE}" "${USER_REQ}" | ||
|
|
||
| # Copy output to target location | ||
| # Note: x2a tool writes files to the source directory (--source-dir) | ||
|
|
@@ -290,10 +322,7 @@ | |
| echo "Working directory: $(pwd)" | ||
|
|
||
| USER_REQ="${USER_PROMPT:-Analyze the module '${MODULE_NAME}' for migration to Ansible}" | ||
| echo "Command: uv run app.py analyze --source-dir ${SOURCE_BASE} \"${USER_REQ}\"" | ||
| ERROR_MESSAGE="Unexpected error during analyze phase. See the job log for details." | ||
| uv run app.py analyze --source-dir "${SOURCE_BASE}" "${USER_REQ}" | ||
| ERROR_MESSAGE="" | ||
| run_x2a uv run app.py analyze --source-dir "${SOURCE_BASE}" "${USER_REQ}" | ||
|
|
||
| # Copy output to target location | ||
| # Note: x2a tool produces migration-plan-{module_name}.md (spaces replaced with underscores) | ||
|
|
@@ -347,15 +376,12 @@ | |
| echo "Working directory: $(pwd)" | ||
|
|
||
| USER_REQ="${USER_PROMPT:-Migrate this module to Ansible}" | ||
| echo "Command: uv run app.py migrate --source-dir ${SOURCE_BASE} --source-technology Chef --high-level-migration-plan ${PROJECT_PATH}/migration-plan.md --module-migration-plan ${OUTPUT_DIR}/migration-plan-${MODULE_NAME_SANITIZED}.md \"${USER_REQ}\"" | ||
| ERROR_MESSAGE="Unexpected error during migrate phase. See the job log for details." | ||
| uv run app.py migrate \ | ||
| run_x2a uv run app.py migrate \ | ||
| --source-dir "${SOURCE_BASE}" \ | ||
| --source-technology Chef \ | ||
| --high-level-migration-plan "${PROJECT_PATH}/migration-plan.md" \ | ||
| --module-migration-plan "${OUTPUT_DIR}/migration-plan-${MODULE_NAME_SANITIZED}.md" \ | ||
| "${USER_REQ}" | ||
| ERROR_MESSAGE="" | ||
|
|
||
| # Copy output to target location | ||
| # Note: x2a tool writes to ansible/roles/{module}/ in the source directory | ||
|
|
@@ -397,15 +423,11 @@ | |
|
|
||
| # Step 1: publish-project — assemble Ansible project from migrated role | ||
| echo "=== Step 1: Assembling Ansible project ===" | ||
| echo "Command: uv run app.py publish-project ${PROJECT_DIR} ${MODULE_NAME}" | ||
|
|
||
| # publish-project reads from {project_id}/modules/{module_name}/ansible/roles/{module_name}/ | ||
| # and writes to {project_id}/ansible-project/ | ||
| # It operates relative to CWD, so we run from TARGET_BASE | ||
| pushd "${TARGET_BASE}" | ||
| ERROR_MESSAGE="Unexpected error during publish phase (publish-project). See the job log for details." | ||
| uv run --project /app /app/app.py publish-project "${PROJECT_DIR}" "${MODULE_NAME}" | ||
| ERROR_MESSAGE="" | ||
| run_x2a uv run --project /app /app/app.py publish-project "${PROJECT_DIR}" "${MODULE_NAME}" | ||
| popd | ||
|
|
||
| # Verify ansible-project was created | ||
|
|
@@ -422,17 +444,14 @@ | |
| # Step 2: publish-aap — register with AAP and sync | ||
| echo "" | ||
| echo "=== Step 2: Publishing to AAP ===" | ||
| echo "Command: uv run app.py publish-aap --target-repo ${TARGET_REPO_URL} --target-branch ${TARGET_REPO_BRANCH} --project-id ${PROJECT_DIR}" | ||
| cd /app | ||
| ERROR_MESSAGE="Unexpected error during publish phase (publish-aap). See the job log for details." | ||
| PUBLISH_OUTPUT=$(uv run app.py publish-aap \ | ||
| run_x2a uv run app.py publish-aap \ | ||
| --target-repo "${TARGET_REPO_URL}" \ | ||
| --target-branch "${TARGET_REPO_BRANCH}" \ | ||
| --project-id "${PROJECT_DIR}" 2>&1 | tee /dev/stderr) | ||
| ERROR_MESSAGE="" | ||
| --project-id "${PROJECT_DIR}" | ||
|
|
||
| # Parse AAP project ID from output and construct URL | ||
| AAP_PROJECT_ID=$(echo "${PUBLISH_OUTPUT}" | grep -oP 'ID: \K[0-9]+' | tail -1) | ||
| # Parse AAP project ID from captured output | ||
| AAP_PROJECT_ID=$(echo "${X2A_OUTPUT}" | grep -oP 'ID: \K[0-9]+' | tail -1) | ||
| if [ -n "${AAP_PROJECT_ID}" ]; then | ||
| ARTIFACTS+=("ansible_project:${AAP_CONTROLLER_URL}/execution/projects/${AAP_PROJECT_ID}/details") | ||
| else | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now that we have this fucntion, what about if we add the log here:
because it's already in all phases, and can be log here without issues, no?