Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

flasher driver: always set system date#743

Merged
mangelajo merged 1 commit intomainfrom
always-set-date-flasher
Nov 11, 2025
Merged

flasher driver: always set system date#743
mangelajo merged 1 commit intomainfrom
always-set-date-flasher

Conversation

@mangelajo
Copy link
Copy Markdown
Member

@mangelajo mangelajo commented Nov 11, 2025

Otherwise, in labs where ntp is not available for the DUTs to use, time setting will be wrong and fls, or CA cert checking will fail.

Summary by CodeRabbit

  • Bug Fixes
    • Improved time synchronization timing for remote device flashing to ensure correct device time configuration during flash operations, enhancing overall reliability.

Otherwise, in labs where ntp is not available for the DUTs to use,
time setting will be wrong and fls, or CA cert checking will fail.
@netlify
Copy link
Copy Markdown

netlify Bot commented Nov 11, 2025

Deploy Preview for jumpstarter-docs ready!

Name Link
🔨 Latest commit aa8022a
🔍 Latest deploy log https://app.netlify.com/projects/jumpstarter-docs/deploys/69138ce267c0bd0008217e4a
😎 Deploy Preview https://deploy-preview-743--jumpstarter-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 11, 2025

Walkthrough

Remote time synchronization in the flasher client was relocated from the SSL setup phase to occur after network configuration during the flash operation, ensuring the DUT time matches the local system before flashing begins.

Changes

Cohort / File(s) Summary
Remote time sync refactoring
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py
Moved time synchronization logic from _setup_flasher_ssl to _perform_flash_operation (post-DHCP). Now syncs remote DUT time via date -s @{timestamp} and waits for login prompt after network setup rather than during SSL initialization.

Sequence Diagram

sequenceDiagram
    participant Local as Local System
    participant Remote as Remote DUT
    
    rect rgb(220, 240, 255)
    Note over Local,Remote: Old flow: time sync during SSL setup
    Local->>Remote: _setup_flasher_ssl()
    Remote-->>Local: (time sync occurred here)
    end
    
    rect rgb(240, 255, 240)
    Note over Local,Remote: New flow: time sync after network setup
    Local->>Remote: _perform_flash_operation()
    Local->>Remote: udhcpc (network setup)
    Remote-->>Local: network ready
    Local->>Remote: date -s @{timestamp}
    Remote-->>Local: time synced
    Local->>Remote: wait for login prompt
    Remote-->>Local: login prompt received
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Timing dependency verification: Ensure time synchronization at the new location doesn't race with other setup operations or cause issues if network setup fails.
  • Error handling: Verify that the relocated logic properly handles failures (e.g., if the remote date command fails or login prompt is never received).
  • State consistency: Confirm that moving this logic doesn't leave the DUT in an inconsistent state if the flash operation is interrupted between network setup and time sync.

Poem

🐰 Time takes its place, not too soon, not late,
After the network awakens, now we synchronize fate!
From SSL's dawn to Flash's bright hour,
The DUT's clock gains its truest power. ⏰✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'flasher driver: always set system date' directly and clearly summarizes the main change: ensuring system date is always set in the flasher driver to address time synchronization issues in labs without NTP.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch always-set-date-flasher

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mangelajo mangelajo requested a review from bennyz November 11, 2025 19:24
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa2a36b and aa8022a.

📒 Files selected for processing (1)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-11-05T13:31:39.304Z
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:100-101
Timestamp: 2025-11-05T13:31:39.304Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, the `flash()` method and its CLI command intentionally have different defaults for `fls_version`: the method defaults to `""` (empty string) while the CLI defaults to `"0.1.5"`. This is by design to provide CLI users with a convenient default while keeping the programmatic API ready for when FLS is included in the flasher images.

Applied to files:

  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py
📚 Learning: 2025-11-05T13:33:24.741Z
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:476-486
Timestamp: 2025-11-05T13:33:24.741Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, the FLS flasher download in _flash_with_fls() hardcodes "aarch64-linux" architecture because the flasher always targets ARM devices currently.

Applied to files:

  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py
📚 Learning: 2025-11-05T13:45:58.271Z
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:15-15
Timestamp: 2025-11-05T13:45:58.271Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, pexpect is intentionally used as a transitive dependency through the jumpstarter-driver-pyserial package. The flashers package does not declare pexpect as a direct dependency because the pyserial driver package is intended to control the pexpect version.

Applied to files:

  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py
🧬 Code graph analysis (1)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1)
examples/soc-pytest/jumpstarter_example_soc_pytest/test_on_rpi4.py (1)
  • console (20-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: build
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: e2e

Comment on lines +332 to +337
# make sure that the remote system has the right time without using NTP
# otherwise SSL certificate verification will fail
self.logger.info("Setting the remote DUT time to match the local system time")
current_timestamp = int(time.time())
console.sendline(f"date -s @{current_timestamp}")
console.expect(manifest.spec.login.prompt, timeout=EXPECT_TIMEOUT_DEFAULT)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling to make time synchronization retryable.

The time synchronization logic correctly addresses the TLS certificate verification issue in labs without NTP. However, unlike the udhcpc block above (lines 322-330), this code lacks error handling. If console.expect() times out or another exception occurs, it won't be wrapped in FlashRetryableError, preventing the retry logic from working as intended.

Apply this diff to add consistent error handling:

             except Exception as e:
                 self.logger.error(f"Error running udhcpc: {e}")
                 raise FlashRetryableError(f"Error running udhcpc: {e}") from e
 
-            # make sure that the remote system has the right time without using NTP
-            # otherwise SSL certificate verification will fail
-            self.logger.info("Setting the remote DUT time to match the local system time")
-            current_timestamp = int(time.time())
-            console.sendline(f"date -s @{current_timestamp}")
-            console.expect(manifest.spec.login.prompt, timeout=EXPECT_TIMEOUT_DEFAULT)
+            # make sure that the remote system has the right time without using NTP
+            # otherwise SSL certificate verification will fail
+            try:
+                self.logger.info("Setting the remote DUT time to match the local system time")
+                current_timestamp = int(time.time())
+                console.sendline(f"date -s @{current_timestamp}")
+                console.expect(manifest.spec.login.prompt, timeout=EXPECT_TIMEOUT_DEFAULT)
+            except pexpect.TIMEOUT as e:
+                self.logger.error(f"Timeout waiting for date command to complete: {e}")
+                raise FlashRetryableError("Timeout waiting for date command to complete") from e
+            except Exception as e:
+                self.logger.error(f"Error setting remote time: {e}")
+                raise FlashRetryableError(f"Error setting remote time: {e}") from e
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# make sure that the remote system has the right time without using NTP
# otherwise SSL certificate verification will fail
self.logger.info("Setting the remote DUT time to match the local system time")
current_timestamp = int(time.time())
console.sendline(f"date -s @{current_timestamp}")
console.expect(manifest.spec.login.prompt, timeout=EXPECT_TIMEOUT_DEFAULT)
# make sure that the remote system has the right time without using NTP
# otherwise SSL certificate verification will fail
try:
self.logger.info("Setting the remote DUT time to match the local system time")
current_timestamp = int(time.time())
console.sendline(f"date -s @{current_timestamp}")
console.expect(manifest.spec.login.prompt, timeout=EXPECT_TIMEOUT_DEFAULT)
except pexpect.TIMEOUT as e:
self.logger.error(f"Timeout waiting for date command to complete: {e}")
raise FlashRetryableError("Timeout waiting for date command to complete") from e
except Exception as e:
self.logger.error(f"Error setting remote time: {e}")
raise FlashRetryableError(f"Error setting remote time: {e}") from e
🤖 Prompt for AI Agents
In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py
around lines 332 to 337, the time sync block lacks error handling so exceptions
from console.expect() won't be treated as retryable; wrap the date command and
console.expect call in a try/except, catch Exception, log the exception with
context via self.logger.warning or self.logger.exception, and raise
FlashRetryableError(...) (same pattern and message style used in the udhcpc
block above) so the caller can retry the operation.

@mangelajo mangelajo merged commit 2d1dcd3 into main Nov 11, 2025
19 checks passed
@mangelajo mangelajo deleted the always-set-date-flasher branch November 11, 2025 20:06
@jumpstarter-backport-bot
Copy link
Copy Markdown

Successfully created backport PR for release-0.7:

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants