flashers: chunk long credentials over serial#214
Conversation
📝 WalkthroughWalkthroughRemoved CLI OCI credential options; added environment-based OCI credential resolution for oci:// image paths; changed FLS credential-file creation to write base64-encoded chunks and decode them on target. Tests added/updated to cover env resolution, chunking, and long-token handling. Changes
Sequence DiagramsequenceDiagram
participant CLI as User/CLI
participant Client as BaseFlasherClient
participant Env as Environment
participant FS as FileSystem
participant FLS as FlasherService
CLI->>Client: flash(image="oci://...", oci_username=None, oci_password=None)
Client->>Client: detect "oci://" scheme
Client->>Env: read OCI_USERNAME & OCI_PASSWORD
Env-->>Client: return username/password or None
Client->>Client: _resolve_oci_credentials() -> (user, pass)
Client->>FS: write /tmp/fls_creds.b64 (base64 chunks)
FS-->>Client: chunks written
Client->>FS: decode .b64 -> /tmp/fls_creds
Client->>FS: chmod 600 /tmp/fls_creds
Client->>FLS: call FLS with credential file path
FLS->>FS: read /tmp/fls_creds
FLS-->>Client: flash completed
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
python/packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1)
1318-1321:⚠️ Potential issue | 🟠 MajorThe
.b64temp file containing encoded credentials is never cleaned up.
_cleanup_fls_oci_credential_fileremoves onlycreds_filebut leaves{creds_file}.b64on disk. While base64 is not encryption, the file still contains recoverable credentials.🔒 Proposed fix: also remove the .b64 file
def _cleanup_fls_oci_credential_file(self, console, prompt: str, creds_file: str): with self._temporarily_disable_console_debug_stream(console): console.sendline(f"rm -f {shlex.quote(creds_file)}") console.expect(prompt, timeout=EXPECT_TIMEOUT_DEFAULT) + console.sendline(f"rm -f {shlex.quote(creds_file + '.b64')}") + console.expect(prompt, timeout=EXPECT_TIMEOUT_DEFAULT)
🤖 Fix all issues with AI agents
In
`@python/packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py`:
- Around line 138-139: The docstring string literal for the flash method was
misplaced below _resolve_oci_credentials and is now a no-op; move the
triple-quoted string """Flash image to DUT""" directly beneath the def
flash(...): signature so it becomes the actual docstring for the flash method
(update the def flash in jumpstarter_driver_flashers.client to place the
docstring immediately after the def line and remove the stray string below
_resolve_oci_credentials).
🧹 Nitpick comments (2)
python/packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1)
583-583: Redaction scope narrowed to onlyoci_password— intentional?Previously both
oci_usernameandoci_passwordwere redacted. Now only the password is redacted. If the username is a service account name this is fine, but for some OCI registries the username can also be sensitive (e.g., API key IDs). Consider whetheroci_usernameshould remain redacted.python/packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client_test.py (1)
181-221: Good long-token chunking test, but the cleanup test doesn't cover the.b64file.The chunking and roundtrip assertions are solid. However, none of the tests verify that
.b64temp file is cleaned up — which aligns with the gap flagged inclient.py. Once the cleanup fix is applied, consider adding an assertion for it here.Also,
MockConsoleis duplicated between this test andtest_setup_and_cleanup_fls_oci_credential_file(line 135). Consider extracting it to module level.
05e817b to
634cd79
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@python/packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py`:
- Around line 1279-1311: The temp base64 file (b64_file) created in
_setup_fls_oci_credential_file is never removed; after decoding and setting
perms on creds_file, send a console command to delete the intermediate file
(e.g., console.sendline(f"rm -f {shlex.quote(b64_file)}") followed by
console.expect(prompt,...)) so /tmp/fls_creds.b64 is cleaned up; ideally place
this rm call after the chmod step inside the with
self._temporarily_disable_console_debug_stream(console) block (or ensure it runs
in a finally/cleanup path if you want guaranteed removal on errors).
🧹 Nitpick comments (2)
python/packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client_test.py (2)
164-164: Moveimport base64to the top of the test file.
base64is imported inline in two test functions. Hoisting it to the module level keeps the style consistent and avoids redundant imports.Proposed fix
+import base64 import shlex from concurrent.futures import CancelledErrorThen remove the inline
import base64on lines 164 and 210.Also applies to: 210-210
182-192:MockConsoleis duplicated across two tests — consider extracting it.The identical
MockConsoleclass appears in bothtest_setup_fls_oci_credential_file(line 135) andtest_setup_fls_oci_credential_file_chunks_long_tokens(line 182). Extracting it to module scope would reduce duplication.
2e49ea2 to
5656389
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
python/packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1)
1296-1305:⚠️ Potential issue | 🟡 MinorStale error message references removed CLI options.
_validate_oci_credentialsstill mentions--oci-usernameand--oci-password, but those CLI flags were removed in this PR. CLI users who hit this error will see instructions that don't apply.Proposed fix
if bool(username) != bool(password): raise click.ClickException( - "OCI authentication requires both --oci-username and --oci-password " - "(or OCI_USERNAME and OCI_PASSWORD environment variables)" + "OCI authentication requires both OCI_USERNAME and OCI_PASSWORD " + "environment variables (or both oci_username and oci_password arguments)" )
🧹 Nitpick comments (2)
python/packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1)
1353-1385: Chunked base64 credential writing — solid approach for serial buffer limits.The implementation correctly:
- Encodes credentials as base64 to avoid shell-special characters in raw content.
- Splits into 512-byte chunks to stay well within typical serial line buffer limits.
- Uses
shlex.quoteon all dynamic values for injection safety.- Decodes on-target with
base64 -d.One minor note: the
umask 077on line 1367 persists for the rest of the shell session, which could restrict permissions on files created by subsequent commands (e.g.,flswriting temp files). In a single-user initramfs context this is likely harmless, but wrapping it in a subshell would be more defensive:Optional: scope umask to a subshell
- console.sendline(f"umask 077 && true > {shlex.quote(creds_file)}") + console.sendline(f"(umask 077 && true > {shlex.quote(creds_file)})")python/packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client_test.py (1)
183-223: Good test for the long-token chunking behavior.Validates that a ~1400-char JWT-like token produces multiple chunks, each within serial buffer limits, and that the full roundtrip decode is correct.
One small observation: the assertion on line 222 relies on
shlex.quotenot adding quotes around a purely alphanumeric string (which is correct per CPython'sshlex._find_unsaferegex). If the test token ever includes characters like+,/, or=(common in real JWTs),shlex.quotewould wrap the token, and the assertion would need adjustment. Consider adding a brief comment or a follow-up test with a more realistic JWT character set.
serial access cannot handle very long strings we need to pass, for example, jwt token from openshift. instead chunk into smaller pieces and write incrementally also remove the cmdline --oci-username and --oci-password, and leave only env vars Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com> Assisted-by: claude-opus-4.6
5656389 to
1bc077b
Compare
serial access cannot handle very long strings we need to pass, for example, jwt token from openshift. instead chunk into smaller pieces and write incrementally
also remove the cmdline --oci-username and --oci-password, and leave only env vars
Summary by CodeRabbit
New Features
Documentation
Improvements
Tests