8000 [feat] Add wait-ready command to check Multipass daemon readiness by rluna319 · Pull Request #4145 · canonical/multipass · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

[feat] Add wait-ready command to check Multipass daemon readiness #4145

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

rluna319
Copy link
@rluna319 rluna319 commented Jun 6, 2025

Feature: Add multipass wait-ready command

Description:
This PR introduces a new CLI command, multipass wait-ready. This command allows users and scripts to pause execution until the Multipass daemon is fully initialized and ready to accept requests. This is particularly beneficial for automation workflows that need to ensure the daemon is operational before proceeding with other Multipass operations.

The wait-ready command works by:

  1. Initially polling the daemon's gRPC socket until it becomes available.
  2. Once the socket is available, it sends a WaitReady request to the daemon.
  3. The daemon, upon receiving this request, verifies its readiness by attempting to update image manifests (which implicitly checks connectivity to image servers).
  4. The command supports a --timeout option (in seconds). If the daemon isn't ready within the specified timeout, the command exits with an error. If no timeout is given, it waits indefinitely.
  5. An animated spinner and context-relevant message provide user feedback during the waiting period.

Motivation:

  • Improves the reliability of automated scripts and CI/CD pipelines that interact with Multipass by providing a deterministic way to wait for daemon initialization.
  • Addresses scenarios where subsequent Multipass commands might fail if the daemon is still starting up.

Related Issues:
Fixes #452
Fixes #3723

Key Implementation Changes:

  • Client-side (wait_ready.cpp): New command logic, including retry for socket connection, timeout handling (reusing mp::cmd::parse_timeout), and spinner integration.
  • Protocol (multipass.proto): Added WaitReadyRequest / WaitReadyReply messages and WaitReady RPC method.
  • Daemon-side (daemon_rpc.cpp, daemon.cpp):
    • New gRPC service handler in daemon_rpc.cpp.
    • Core readiness check in daemon.cpp leverages the existing wait_update_manifests_all_and_optionally_applied_force() function.

How to Test:

  1. Build this branch and $ cd build.
  2. Ensure the Multipass daemon is stopped.
  3. To verify --timeout, simply run the wait-ready command with the --timeout option:
$ ./bin/multipass wait-ready --timeout 5

Be sure not to start up the daemon first or the command might exit before the timeout.

  • Expected: Info message "Waiting for Multipass daemon to be ready...", spinner is shown, command times out after ~5 seconds with an appropriate error message "Timed out waiting for Multipass daemon to be ready."
  1. (Optional) To replicate the issue that happens when the client tries to use the daemon before its ready (without wait-ready), start up the daemon and immediately use multipass launch:
$ sudo -v
$ (sudo ./bin/multipassd &) && ./bin/multipass launch
  1. Stop the Multipass daemon
$ sudo pkill multipassd
  1. To verify wait-ready command solves the issue, fit the wait-ready command between daemon startup and multipass launch:
$ sudo -v
$ (sudo ./bin/multipassd &) && ./bin/multipass wait-ready && ./bin/multipass launch

Optionally, add --timeout if desired.

  • Expected: Info message "Waiting for Multipass daemon to be ready...", spinner is shown, command exits successfully (ReturnCode::Ok) once the daemon is ready (i.e., can connect to image servers) and the client begins retrieving the default release image for the multipass launch process. You may Ctrl+C here to terminate the launch process.

Points for Reviewers:

  • Confirmation that using wait_update_manifests_all_and_optionally_applied_force(true) is an appropriate and robust proxy for overall daemon readiness.
  • Feedback on the client-side error messages and user experience (spinner, timeout message) is appreciated. The current spinner implementation addresses @ricab's suggestion in Command suggestion: waitready #452.
  • Unit Tests: Per @ricab 's comments in issue Command suggestion: waitready #452, unit tests have not yet been implemented for this initial PR to facilitate earlier review. I am prepared to add them based on feedback.

This commit introduces the `multipass wait-ready` command. This new
command allows clients to block until the Multipass daemon is fully
initialized and ready to accept requests.

The command first polls the daemon until its gRPC socket is available.
Once the daemon is reachable and receives the `WaitReady` request, it
verifies its readiness by attempting to update image manifests, which
implicitly checks connectivity to image servers.

Users can specify a `--timeout` (in seconds), after which the command
will terminate with an error if the daemon is not yet ready. If no
timeout is specified, the command will wait indefinitely until the
daemon is ready or some other error occurs.

Implementation Details:
- Client-side (`wait_ready.cpp`, `wait_ready.h`):
  - Created the `WaitReady` command logic and its header file.
  - Implemented a retry loop to poll for daemon socket availability.
  - Utilized the existing `mp::cmd::parse_timeout()` function from
    `common_cli.h` to handle the `--timeout` option.
  - Integrated `AnimatedSpinner` for visual feedback during the
    waiting period.
  - Added error handling for various failure conditions (e.g., timeout,
    daemon connection errors).
- Protocol (`multipass.proto`):
  - Defined the `WaitReadyRequest` and `WaitReadyReply` messages and
    the `WaitReady` RPC method within the `Multipass` service.
- Daemon-side:
  - Added the `wait_ready` gRPC service handler function in
    `daemon_rpc.cpp` to process incoming requests.
  - Implemented the core `wait_ready` logic in `daemon.cpp`, which
    leverages the existing
    `wait_update_manifests_all_and_optionally_applied_force()`
    function to check image server connectivity.
- Testing (`tests/mock_client_rpc.h`):
  - Added mock methods for `wait_readyRaw`, `Asyncwait_readyRaw`,
    and `PrepareAsyncwait_readyRaw` to `MockRpcStub` to support
    testing of the new RPC endpoint.
@ricab
Copy link
Collaborator
ricab commented Jun 6, 2025

Hey @rluna319, thank you for this! We'll review when we get a chance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants
0