Commit 061feb2
committed
tasks: quote argument tokens for the shell
run_ansible_in_environment joins a list of arguments with plain spaces and
runs the result through subprocess.Popen(..., shell=True), so any `-e`
value containing a shell metacharacter is parsed by /bin/sh. A tempest
regex alternation is the motivating case:
osism apply tempest -e 'tempest_include_regex=(A|B)'
/bin/sh: 1: Syntax error: "(" unexpected
The command dies before ansible runs. This affects every `osism apply ...
-e key=value` whose value contains a metacharacter, across all workers.
Two things constrain the fix.
First, shlex.quote() per list element is wrong, and
test_run_ansible_list_multitoken_element_word_split_not_quoted exists to
prevent it: callers deliberately pack several shell words into ONE element
and rely on the outer shell to tokenize them (commands/set.py and
commands/noset.py pass ["-e status=True", f"-l {host}"];
commands/validate.py and commands/apply.py prepend "-e kolla_action=...").
The run-<environment>.sh scripts forward args via "$@" without
re-tokenizing, so that step is load-bearing; quoting whole elements glues
"-e status=True" into one token and breaks -e/-l parsing.
Second, str.split() is not sufficient either. An element may use quoting
or a backslash to hold whitespace inside a single value, and splitting on
raw whitespace cuts that value into malformed arguments:
element /bin/sh today str.split() + quote
-e foo='hello world' [-e][foo=hello world] [-e][foo='hello][world']
-e path=a\ b [-e][path=a b] [-e][path=a\][b]
So tokenize each element the way the shell would, with shlex.split(), then
quote the resulting tokens. That reproduces today's tokenization for
quoted and escaped whitespace while making metacharacters safe.
shlex.split() raises on unbalanced quoting, where /bin/sh merely fails
with its own error. Such elements are emitted verbatim so the failure mode
stays a shell error rather than becoming a worker traceback.
Tests written first and watched fail. test_run_ansible_multitoken_element_
tokens_quoted_individually pins both properties at once -- a multi-token
element still tokenizes AND a metacharacter inside one of its tokens is
quoted -- and four more cover single-quoted, double-quoted and
backslash-escaped whitespace plus the unbalanced-quote passthrough.
Verified: 86 passed in tests/unit/tasks/test_init.py including the
existing guard; 3154 passed / 4 pre-existing xfail across tests/unit; and
end-to-end on a live OSISM 10.2.0 cluster, where the alternation above
previously failed with the syntax error and now selects and runs both
tests (Passed: 2, Failed: 0).
Assisted-by: Claude:claude-opus-5
Signed-off-by: Roger Luethi <luethi@osism.tech>1 parent b4a3185 commit 061feb2
2 files changed
Lines changed: 85 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
173 | 174 | | |
174 | 175 | | |
175 | 176 | | |
176 | | - | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
177 | 211 | | |
178 | 212 | | |
179 | 213 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
385 | 385 | | |
386 | 386 | | |
387 | 387 | | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
388 | 438 | | |
389 | 439 | | |
390 | 440 | | |
| |||
0 commit comments