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.map(|_| ())
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            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.map(|_| ())
78        }
79        ComponentSubcommand::Stop(args) => {
80            stop_cmd(args.query, lifecycle_controller, realm_query, writer).await.map(|_| ())
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            use std::io::Write as _;
93            let result = graph_cmd(args.filter, args.orientation, realm_query).await?;
94            writeln!(writer, "{}", result)?;
95            Ok(())
96        }
97        ComponentSubcommand::Run(args) => {
98            let config_overrides = resolve_raw_config_overrides(
99                &realm_query,
100                &args.moniker,
101                &args.url.to_string(),
102                &args.config,
103            )
104            .await?;
105            run_cmd(
106                args.moniker,
107                args.url,
108                args.recreate,
109                args.connect_stdio,
110                config_overrides,
111                || {
112                    async {
113                        connect_to_protocol_at_path::<fsys::LifecycleControllerMarker>(
114                            "/svc/fuchsia.sys2.LifecycleController.root",
115                        )
116                    }
117                    .boxed()
118                },
119                writer,
120            )
121            .await
122        }
123        ComponentSubcommand::Copy(args) => {
124            copy_cmd(&realm_query, args.paths, args.verbose, writer).await
125        }
126        ComponentSubcommand::Route(args) => {
127            route_cmd_print(args.target, args.filter, route_validator, realm_query, writer).await
128        }
129        ComponentSubcommand::Storage(args) => match args.subcommand {
130            StorageSubcommand::Copy(copy_args) => {
131                storage_copy_cmd(
132                    args.provider,
133                    args.capability,
134                    copy_args.source_path,
135                    copy_args.destination_path,
136                    realm_query,
137                )
138                .await
139            }
140            StorageSubcommand::Delete(delete_args) => {
141                storage_delete_cmd(args.provider, args.capability, delete_args.path, realm_query)
142                    .await
143            }
144            StorageSubcommand::List(list_args) => {
145                let entries =
146                    storage_list_cmd(args.provider, args.capability, list_args.path, realm_query)
147                        .await?;
148                storage_list_cmd_write(entries, &mut writer)
149            }
150            StorageSubcommand::MakeDirectory(make_dir_args) => {
151                storage_make_directory_cmd(
152                    args.provider,
153                    args.capability,
154                    make_dir_args.path,
155                    realm_query,
156                )
157                .await
158            }
159        },
160        ComponentSubcommand::Collection(args) => match args.subcommand {
161            CollectionSubcommand::List(_) => collection_list_cmd(realm_query, writer).await,
162            CollectionSubcommand::Show(show_args) => {
163                collection_show_cmd(show_args.query, realm_query, writer).await
164            }
165        },
166        ComponentSubcommand::Config(args) => match args.subcommand {
167            ConfigSubcommand::Set(SetArgs { query, key_values, reload }) => {
168                config_set_cmd(
169                    query,
170                    key_values,
171                    reload,
172                    lifecycle_controller,
173                    realm_query,
174                    config_override,
175                    writer,
176                )
177                .await
178            }
179            ConfigSubcommand::Unset(UnsetArgs { query, reload }) => {
180                config_unset_cmd(
181                    query,
182                    reload,
183                    lifecycle_controller,
184                    realm_query,
185                    config_override,
186                    writer,
187                )
188                .await
189            }
190            ConfigSubcommand::List(ConfigListArgs { query }) => {
191                config_list_cmd(query, realm_query, writer).await
192            }
193        },
194    }
195}