Skip to main content

component/
lib.rs

1// Copyright 2023 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
5mod args;
6
7use crate::args::*;
8use anyhow::Result;
9use component_debug::cli::*;
10use component_debug::config::resolve_raw_config_overrides;
11use component_debug::copy::copy_cmd;
12use fidl_fuchsia_dash as fdash;
13use fidl_fuchsia_sys2 as fsys;
14use fuchsia_component::client::{connect_to_protocol, connect_to_protocol_at_path};
15use futures::FutureExt;
16use socket_to_stdio::Stdout;
17
18pub async fn exec() -> Result<()> {
19    let args: ComponentArgs = argh::from_env();
20
21    let mut writer = std::io::stdout();
22    let realm_query =
23        connect_to_protocol_at_path::<fsys::RealmQueryMarker>("/svc/fuchsia.sys2.RealmQuery.root")?;
24    let route_validator = connect_to_protocol_at_path::<fsys::RouteValidatorMarker>(
25        "/svc/fuchsia.sys2.RouteValidator.root",
26    )?;
27    let lifecycle_controller = connect_to_protocol_at_path::<fsys::LifecycleControllerMarker>(
28        "/svc/fuchsia.sys2.LifecycleController.root",
29    )?;
30    let config_override = connect_to_protocol_at_path::<fsys::ConfigOverrideMarker>(
31        "/svc/fuchsia.sys2.ConfigOverride.root",
32    )?;
33
34    match args.subcommand {
35        ComponentSubcommand::Show(args) => {
36            show_cmd_print(args.query, realm_query, writer, true).await
37        }
38        ComponentSubcommand::Create(args) => {
39            let config_overrides = resolve_raw_config_overrides(
40                &realm_query,
41                &args.moniker,
42                &args.url.to_string(),
43                &args.config,
44            )
45            .await?;
46            create_cmd(args.url, args.moniker, config_overrides, lifecycle_controller, writer).await
47        }
48        ComponentSubcommand::Destroy(args) => {
49            destroy_cmd(args.query, lifecycle_controller, realm_query, writer).await
50        }
51        ComponentSubcommand::Resolve(args) => {
52            resolve_cmd(args.query, lifecycle_controller, realm_query, writer).await
53        }
54        ComponentSubcommand::Explore(args) => {
55            // TODO(https://fxbug.dev/296283299): Verify that the optional Launcher protocol is
56            // available before connecting.
57            let dash_launcher = connect_to_protocol::<fdash::LauncherMarker>()?;
58            // TODO(https://fxbug.dev/42077838): Use Stdout::raw instead, when a command is
59            // not provided.
60            let stdout = Stdout::buffered();
61
62            #[allow(clippy::large_futures)]
63            explore_cmd(
64                args.query,
65                args.ns_layout,
66                args.command,
67                args.tools,
68                dash_launcher,
69                realm_query,
70                stdout,
71            )
72            .await
73        }
74        ComponentSubcommand::Reload(args) => {
75            reload_cmd(args.query, lifecycle_controller, realm_query, writer).await
76        }
77        ComponentSubcommand::Start(args) => {
78            start_cmd(args.query, lifecycle_controller, realm_query, writer).await
79        }
80        ComponentSubcommand::Stop(args) => {
81            stop_cmd(args.query, lifecycle_controller, realm_query, writer).await
82        }
83        ComponentSubcommand::Doctor(args) => {
84            doctor_cmd_print(args.query, route_validator, realm_query, writer).await
85        }
86        ComponentSubcommand::Capability(args) => {
87            capability_cmd(args.capability_name, realm_query, writer).await
88        }
89        ComponentSubcommand::List(args) => {
90            list_cmd_print(args.filter, args.verbose, realm_query, writer).await
91        }
92        ComponentSubcommand::Graph(args) => {
93            use std::io::Write as _;
94            let result = graph_cmd(args.filter, args.orientation, realm_query).await?;
95            writeln!(writer, "{}", result)?;
96            Ok(())
97        }
98        ComponentSubcommand::Run(args) => {
99            let config_overrides = resolve_raw_config_overrides(
100                &realm_query,
101                &args.moniker,
102                &args.url.to_string(),
103                &args.config,
104            )
105            .await?;
106            run_cmd(
107                args.moniker,
108                args.url,
109                args.recreate,
110                args.connect_stdio,
111                config_overrides,
112                || {
113                    async {
114                        connect_to_protocol_at_path::<fsys::LifecycleControllerMarker>(
115                            "/svc/fuchsia.sys2.LifecycleController.root",
116                        )
117                    }
118                    .boxed()
119                },
120                writer,
121            )
122            .await
123        }
124        ComponentSubcommand::Copy(args) => {
125            copy_cmd(&realm_query, args.paths, args.verbose, writer).await
126        }
127        ComponentSubcommand::Route(args) => {
128            route_cmd_print(args.target, args.filter, route_validator, realm_query, writer).await
129        }
130        ComponentSubcommand::Storage(args) => match args.subcommand {
131            StorageSubcommand::Copy(copy_args) => {
132                storage_copy_cmd(
133                    args.provider,
134                    args.capability,
135                    copy_args.source_path,
136                    copy_args.destination_path,
137                    realm_query,
138                )
139                .await
140            }
141            StorageSubcommand::Delete(delete_args) => {
142                storage_delete_cmd(args.provider, args.capability, delete_args.path, realm_query)
143                    .await
144            }
145            StorageSubcommand::List(list_args) => {
146                let entries =
147                    storage_list_cmd(args.provider, args.capability, list_args.path, realm_query)
148                        .await?;
149                storage_list_cmd_write(entries, &mut writer)
150            }
151            StorageSubcommand::MakeDirectory(make_dir_args) => {
152                storage_make_directory_cmd(
153                    args.provider,
154                    args.capability,
155                    make_dir_args.path,
156                    realm_query,
157                )
158                .await
159            }
160        },
161        ComponentSubcommand::Collection(args) => match args.subcommand {
162            CollectionSubcommand::List(_) => collection_list_cmd(realm_query, writer).await,
163            CollectionSubcommand::Show(show_args) => {
164                collection_show_cmd(show_args.query, realm_query, writer).await
165            }
166        },
167        ComponentSubcommand::Config(args) => match args.subcommand {
168            ConfigSubcommand::Set(SetArgs { query, key_values, reload }) => {
169                config_set_cmd(
170                    query,
171                    key_values,
172                    reload,
173                    lifecycle_controller,
174                    realm_query,
175                    config_override,
176                    writer,
177                )
178                .await
179            }
180            ConfigSubcommand::Unset(UnsetArgs { query, reload }) => {
181                config_unset_cmd(
182                    query,
183                    reload,
184                    lifecycle_controller,
185                    realm_query,
186                    config_override,
187                    writer,
188                )
189                .await
190            }
191            ConfigSubcommand::List(ConfigListArgs { query }) => {
192                config_list_cmd(query, realm_query, writer).await
193            }
194        },
195    }
196}