Skip to main content

iquery/commands/
target.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::commands::types::DiagnosticsProvider;
6use crate::commands::utils::*;
7use crate::types::Error;
8use diagnostics_data::{Data, Inspect};
9use diagnostics_reader::{ArchiveReader, RetryConfig};
10use fidl::endpoints::DiscoverableProtocolMarker;
11use flex_fuchsia_diagnostics::{ArchiveAccessorMarker, ArchiveAccessorProxy, Selector};
12use flex_fuchsia_sys2 as fsys2;
13use moniker::Moniker;
14
15const ROOT_ARCHIVIST: &str = "bootstrap/archivist";
16
17pub struct ArchiveAccessorProvider {
18    query_proxy: fsys2::RealmQueryProxy,
19}
20
21impl ArchiveAccessorProvider {
22    pub fn new(proxy: fsys2::RealmQueryProxy) -> Self {
23        Self { query_proxy: proxy }
24    }
25}
26
27impl DiagnosticsProvider for ArchiveAccessorProvider {
28    async fn snapshot(
29        &self,
30        accessor: Option<&str>,
31        selectors: impl IntoIterator<Item = Selector>,
32    ) -> Result<Vec<Data<Inspect>>, Error> {
33        let archive = connect_to_accessor_selector(accessor, &self.query_proxy).await?;
34        ArchiveReader::inspect()
35            .with_archive(archive)
36            .retry(RetryConfig::never())
37            .add_selectors(selectors.into_iter())
38            .snapshot()
39            .await
40            .map_err(Error::Fetch)
41    }
42
43    async fn get_accessor_paths(&self) -> Result<Vec<String>, Error> {
44        get_accessor_selectors(&self.query_proxy).await
45    }
46
47    fn realm_query(&self) -> &fsys2::RealmQueryProxy {
48        &self.query_proxy
49    }
50}
51
52/// Connect to `fuchsia.diagnostics.*ArchivistAccessor` with the provided selector string.
53/// The selector string can be in the form of "<moniker>:<service_name>" or "<moniker>", and it
54/// performs fuzzy matching on both. See `commands::utils::fuzzy_search_accessors` for more
55/// information.
56/// If no selector string is provided, it will try to connect to
57/// `bootstrap/archivist:fuchsia.diagnostics.ArchiveAccessor`.
58pub async fn connect_to_accessor_selector(
59    selector: Option<&str>,
60    query_proxy: &fsys2::RealmQueryProxy,
61) -> Result<ArchiveAccessorProxy, Error> {
62    match selector {
63        Some(s) => {
64            // try to fuzzy search for the moniker and protocol
65            let (moniker, protocol) = fuzzy_search_accessors(s, query_proxy).await?;
66            connect_accessor::<ArchiveAccessorMarker>(&moniker, &protocol, query_proxy).await
67        }
68        None => {
69            let moniker = Moniker::try_from(ROOT_ARCHIVIST).unwrap();
70            connect_accessor::<ArchiveAccessorMarker>(
71                &moniker,
72                ArchiveAccessorMarker::PROTOCOL_NAME,
73                query_proxy,
74            )
75            .await
76        }
77    }
78}