Skip to content

Fix SSHRemoteJobOperator cleanup failing with custom remote_base_dir - #69885

Merged
potiuk merged 1 commit into
apache:mainfrom
harshhh817:fix-ssh-remote-job-custom-base-dir
Aug 1, 2026
Merged

Fix SSHRemoteJobOperator cleanup failing with custom remote_base_dir#69885
potiuk merged 1 commit into
apache:mainfrom
harshhh817:fix-ssh-remote-job-custom-base-dir

Conversation

@harshhh817

Copy link
Copy Markdown
Contributor

Fixes SSHRemoteJobOperator failing at the cleanup step whenever a custom remote_base_dir is used.

The operator accepts (and validates) a custom remote_base_dir at construction time and creates the job directory under it, but build_posix_cleanup_command / build_windows_cleanup_command validated the job directory against the hardcoded default base directory. Result: the remote job runs to completion, then the task fails with

Invalid job directory: '/tmp-data/airflow-ssh-jobs/af_…'. Expected path under '/tmp/airflow-ssh-jobs' for safety.

Fix: thread the operator's configured remote_base_dir through the cleanup builders into _validate_job_dir, falling back to the OS-specific default when unset. The safety property is preserved — the rm -rf target must still live under the base directory the job was actually created under (which was itself validated by _validate_base_dir at operator construction). Both the sync and deferrable (execute_complete) cleanup paths go through the fixed _cleanup_remote_job.

Tests: new unit tests for custom-base-dir acceptance and rejection (posix + windows), plus an operator-level regression test reproducing the exact failure from the issue — verified it fails on main and passes with this change. Full ssh provider unit suite: 49 passed.

closes: #69813


Was generative AI tooling used to co-author this PR?
  • Yes (Claude Code)

Generated-by: Claude Code following the guidelines


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@potiuk

potiuk commented Jul 31, 2026

Copy link
Copy Markdown
Member

Heads-up: #70091 merged a few minutes ago and has put this into conflict — apologies, I reviewed them in sequence and the overlap only became visible once the first landed.

Both PRs modify build_posix_cleanup_command in providers/ssh/src/airflow/providers/ssh/utils/remote_job.py: #70091 changed its body to return f"rm -rf {shlex.quote(job_dir)}", while this PR changes its signature to take base_dir. The two edits are adjacent, and this branch is ~441 commits behind main, so a rebase is needed.

The resolution should be mechanical — keep your signature change and _validate_job_dir(job_dir, "posix", base_dir), and take shlex.quote(job_dir) from main for the rm -rf line. Same pattern for the kill/log-tail builders if you touch them.

On the fix itself, which I did review: the diagnosis is right. _validate_job_dir compares against POSIX_DEFAULT_BASE_DIR unconditionally, so any operator with a custom remote_base_dir fails cleanup with "Invalid job directory" even though the path is legitimate. Passing the operator's own base dir through is the correct fix, and defaulting to the OS constant keeps existing behaviour intact.

No review comments beyond the rebase — happy to look again once it's green.


Drafted-by: Claude Code (Opus 5); reviewed by @potiuk before posting

@potiuk
potiuk force-pushed the fix-ssh-remote-job-custom-base-dir branch from 0095a4f to ea0a187 Compare August 1, 2026 12:38

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the right fix, and of the three PRs opened for this bug it has the strongest tests — it's the only one that pins the negative case on both POSIX and Windows, i.e. that a job dir outside the custom base is still rejected. On a guard function the interesting behaviour is what it refuses, so that matters.

Using (base_dir or DEFAULT) rather than an is None check is also the better failure mode: an empty base dir falls back to the safe default instead of producing a prefix of / that almost any absolute path satisfies. Not reachable today, since _validate_base_dir rejects empty at execute time, but it is the right way round for a security check.

#70091 landed on main while this was open and rewrote the same POSIX command builders to use shlex.quote, which put this branch into conflict. That was merged underneath you, so I have resolved it rather than sending it back:

  • build_posix_cleanup_command now takes both changes — _validate_job_dir(job_dir, "posix", base_dir) together with shlex.quote(job_dir).
  • Your four test_remote_job.py tests and the TestPosixPathQuoting class from #70091 are both kept; they were adjacent additions rather than a genuine conflict.
  • test_cleanup_with_custom_remote_base_dir asserted rm -rf '/tmp-data/...' with hand-written quotes. shlex.quote leaves a path containing no shell metacharacters unquoted, so that assertion needed updating to the unquoted form.

I checked the merged result keeps both properties rather than just compiling:

custom base accepted : rm -rf /data/jobs/job_1
outside base rejected: Invalid job directory '/tmp/airflow-ssh-jobs/j'...
injection quoted     : rm -rf '/tmp/airflow-ssh-jobs/x'"'"'; touch /tmp/pwned; :'"'"''
default base works   : rm -rf /tmp/airflow-ssh-jobs/j

58 tests pass in the ssh unit suite.

Two other PRs were opened for this same bug — #70788 and #70802 — and I am closing both in favour of this one.


Drafted-by: Claude Code (Opus 5); reviewed by @potiuk before posting

The cleanup command builders validated the job directory against the
hardcoded default base directory, so any job started with a custom
remote_base_dir ran to completion and then failed its cleanup step with
"Invalid job directory ... Expected path under '/tmp/airflow-ssh-jobs'".

Thread the operator's configured remote_base_dir through
build_posix_cleanup_command / build_windows_cleanup_command into
_validate_job_dir, falling back to the OS default when unset, so the
safety check still constrains the rm target to the directory the job was
actually created under.

Signed-off-by: Harsh Gupta <harshgupta93198@gmail.com>
@potiuk
potiuk force-pushed the fix-ssh-remote-job-custom-base-dir branch from ea0a187 to d617cd4 Compare August 1, 2026 15:32
@potiuk
potiuk merged commit 9d3b20c into apache:main Aug 1, 2026
83 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:providers provider:ssh ready for maintainer review Set after triaging when all criteria pass.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SSHRemoteJobOperator: inconsistent "remote_base_dir" validation

2 participants