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 fuchsia_component::client::{connect_to_protocol, connect_to_protocol_at_path};
13use futures::FutureExt;
14use socket_to_stdio::Stdout;
15use {fidl_fuchsia_dash as fdash, fidl_fuchsia_sys2 as fsys};
16
17pub async fn exec() -> Result<()> {
18    let args: ComponentArgs = argh::from_env();
19
20    let writer = std::io::stdout();
21    let realm_query =
22        connect_to_protocol_at_path::<fsys::RealmQueryMarker>("/svc/fuchsia.sys2.RealmQuery.root")?;
23    let route_validator = connect_to_protocol_at_path::<fsys::RouteValidatorMarker>(
24        "/svc/fuchsia.sys2.RouteValidator.root",
25    )?;
26    let lifecycle_controller = connect_to_protocol_at_path::<fsys::LifecycleControllerMarker>(
27        "/svc/fuchsia.sys2.LifecycleController.root",
28    )?;
29    let config_override = connect_to_protocol_at_path::<fsys::ConfigOverrideMarker>(
30        "/svc/fuchsia.sys2.ConfigOverride.root",
31    )?;
32
33    match args.subcommand {
34        ComponentSubcommand::Show(args) => {
35            show_cmd_print(args.query, realm_query, writer, true).await
36        }
37        ComponentSubcommand::Create(args) => {
38            let config_overrides = resolve_raw_config_overrides(
39                &realm_query,
40                &args.moniker,
41                &args.url.to_string(),
42                &args.config,
43            )
44            .await?;
45            create_cmd(args.url, args.moniker, config_overrides, lifecycle_controller, writer).await
46        }
47        ComponentSubcommand::Destroy(args) => {
48            destroy_cmd(args.query, lifecycle_controller, realm_query, writer).await
49        }
50        ComponentSubcommand::Resolve(args) => {
51            resolve_cmd(args.query, lifecycle_controller, realm_query, writer).await
52        }
53        ComponentSubcommand::Explore(args) => {
54            // TODO(https://fxbug.dev/296283299): Verify that the optional Launcher protocol is
55            // available before connecting.
56            let dash_launcher = connect_to_protocol::<fdash::LauncherMarker>()?;
57            // TODO(https://fxbug.dev/42077838): Use Stdout::raw instead, when a command is
58            // not provided.
59            let stdout = Stdout::buffered();
60
61            #[allow(clippy::large_futures)]
62            explore_cmd(
63                args.query,
64                args.ns_layout,
65                args.command,
66                args.tools,
67                dash_launcher,
68                realm_query,
69                stdout,
70            )
71            .await
72        }
73        ComponentSubcommand::Reload(args) => {
74            reload_cmd(args.query, lifecycle_controller, realm_query, writer).await
75        }
76        ComponentSubcommand::Start(args) => {
77            start_cmd(args.query, lifecycle_controller, realm_query, writer).await
78        }
79        ComponentSubcommand::Stop(args) => {
80            stop_cmd(args.query, lifecycle_controller, realm_query, writer).await
81        }
82        ComponentSubcommand::Doctor(args) => {
83            doctor_cmd_print(args.query, route_validator, realm_query, writer).await
84        }
85        ComponentSubcommand::Capability(args) => {
86            capability_cmd(args.capability_name, realm_query, writer).await
87        }
88        ComponentSubcommand::List(args) => {
89            list_cmd_print(args.filter, args.verbose, realm_query, writer).await
90        }
91        ComponentSubcommand::Graph(args) => {
92            graph_cmd(args.filter, args.orientation, realm_query, writer).await
93        }
94        ComponentSubcommand::Run(args) => {
95            let config_overrides = resolve_raw_config_overrides(
96                &realm_query,
97                &args.moniker,
98                &args.url.to_string(),
99                &args.config,
100            )
101            .await?;
102            run_cmd(
103                args.moniker,
104                args.url,
105                args.recreate,
106                args.connect_stdio,
107                config_overrides,
108                || {
109                    async {
110                        connect_to_protocol_at_path::<fsys::LifecycleControllerMarker>(
111                            "/svc/fuchsia.sys2.LifecycleController.root",
112                        )
113                    }
114                    .boxed()
115                },
116                writer,
117            )
118            .await
119        }
120        ComponentSubcommand::Copy(args) => {
121            copy_cmd(&realm_query, args.paths, args.verbose, writer).await
122        }
123        ComponentSubcommand::Route(args) => {
124            route_cmd_print(args.target, args.filter, route_validator, realm_query, writer).await
125        }
126        ComponentSubcommand::Storage(args) => match args.subcommand {
127            StorageSubcommand::Copy(copy_args) => {
128                storage_copy_cmd(
129                    args.provider,
130                    args.capability,
131                    copy_args.source_path,
132                    copy_args.destination_path,
133                    realm_query,
134                )
135                .await
136            }
137            StorageSubcommand::Delete(delete_args) => {
138                storage_delete_cmd(args.provider, args.capability, delete_args.path, realm_query)
139                    .await
140            }
141            StorageSubcommand::List(list_args) => {
142                storage_list_cmd(
143                    args.provider,
144                    args.capability,
145                    list_args.path,
146                    realm_query,
147                    writer,
148                )
149                .await
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}