• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "host/commands/cvd/selector/selector_common_parser.h"
18 
19 #include <unistd.h>
20 
21 #include "common/libs/utils/contains.h"
22 #include "common/libs/utils/flag_parser.h"
23 #include "common/libs/utils/users.h"
24 #include "host/commands/cvd/selector/instance_database_utils.h"
25 #include "host/commands/cvd/selector/selector_constants.h"
26 #include "host/commands/cvd/selector/selector_option_parser_utils.h"
27 
28 namespace cuttlefish {
29 namespace selector {
30 
Parse(const uid_t client_uid,cvd_common::Args & selector_args,const cvd_common::Envs & envs)31 Result<SelectorCommonParser> SelectorCommonParser::Parse(
32     const uid_t client_uid, cvd_common::Args& selector_args,
33     const cvd_common::Envs& envs) {
34   std::string system_wide_home = CF_EXPECT(SystemWideUserHome(client_uid));
35   SelectorCommonParser parser(system_wide_home, envs);
36   CF_EXPECT(parser.ParseOptions(selector_args));
37   return std::move(parser);
38 }
39 
SelectorCommonParser(const std::string & client_user_home,const cvd_common::Envs & envs)40 SelectorCommonParser::SelectorCommonParser(const std::string& client_user_home,
41                                            const cvd_common::Envs& envs)
42     : client_user_home_(client_user_home), envs_{envs} {}
43 
HomeOverridden() const44 Result<bool> SelectorCommonParser::HomeOverridden() const {
45   return Contains(envs_, "HOME") && (client_user_home_ != envs_.at("HOME"));
46 }
47 
Home() const48 std::optional<std::string> SelectorCommonParser::Home() const {
49   if (Contains(envs_, "HOME")) {
50     return envs_.at("HOME");
51   }
52   return std::nullopt;
53 }
54 
ParseOptions(cvd_common::Args & selector_args)55 Result<void> SelectorCommonParser::ParseOptions(
56     cvd_common::Args& selector_args) {
57   // Handling name-related options
58   auto group_name_flag =
59       CF_EXPECT(SelectorFlags::Get().GetFlag(SelectorFlags::kGroupName));
60   auto instance_name_flag =
61       CF_EXPECT(SelectorFlags::Get().GetFlag(SelectorFlags::kInstanceName));
62   std::optional<std::string> group_name_opt =
63       CF_EXPECT(group_name_flag.FilterFlag<std::string>(selector_args));
64   std::optional<std::string> instance_name_opt =
65       CF_EXPECT(instance_name_flag.FilterFlag<std::string>(selector_args));
66 
67   NameFlagsParam name_flags_param{.group_name = group_name_opt,
68                                   .instance_names = instance_name_opt};
69   auto parsed_name_flags = CF_EXPECT(HandleNameOpts(name_flags_param));
70   group_name_ = parsed_name_flags.group_name;
71   instance_names_ = parsed_name_flags.instance_names;
72   return {};
73 }
74 
75 Result<SelectorCommonParser::ParsedNameFlags>
HandleNameOpts(const NameFlagsParam & name_flags) const76 SelectorCommonParser::HandleNameOpts(const NameFlagsParam& name_flags) const {
77   std::optional<std::string> group_name_output;
78   std::optional<std::vector<std::string>> instance_names_output;
79   if (name_flags.group_name) {
80     group_name_output = CF_EXPECT(HandleGroupName(name_flags.group_name));
81   }
82 
83   if (name_flags.instance_names) {
84     instance_names_output =
85         std::move(CF_EXPECT(HandleInstanceNames(name_flags.instance_names)));
86   }
87   return {ParsedNameFlags{.group_name = std::move(group_name_output),
88                           .instance_names = std::move(instance_names_output)}};
89 }
90 
HandleInstanceNames(const std::optional<std::string> & per_instance_names) const91 Result<std::vector<std::string>> SelectorCommonParser::HandleInstanceNames(
92     const std::optional<std::string>& per_instance_names) const {
93   CF_EXPECT(per_instance_names && !per_instance_names.value().empty());
94 
95   auto instance_names =
96       CF_EXPECT(SeparateButWithNoEmptyToken(per_instance_names.value(), ","));
97   for (const auto& instance_name : instance_names) {
98     CF_EXPECT(IsValidInstanceName(instance_name));
99   }
100   std::unordered_set<std::string> duplication_check{instance_names.cbegin(),
101                                                     instance_names.cend()};
102   CF_EXPECT(duplication_check.size() == instance_names.size());
103   return instance_names;
104 }
105 
HandleGroupName(const std::optional<std::string> & group_name) const106 Result<std::string> SelectorCommonParser::HandleGroupName(
107     const std::optional<std::string>& group_name) const {
108   CF_EXPECT(group_name && !group_name.value().empty());
109   CF_EXPECT(IsValidGroupName(group_name.value()), group_name.value()
110                                                       << " failed");
111   return {group_name.value()};
112 }
113 
114 }  // namespace selector
115 }  // namespace cuttlefish
116