1 /* 2 * Copyright (C) 2022 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 #pragma once 18 19 #include <sys/types.h> 20 21 #include <optional> 22 #include <string> 23 #include <unordered_map> 24 #include <unordered_set> 25 #include <vector> 26 27 #include "common/libs/utils/result.h" 28 #include "host/commands/cvd/selector/selector_common_parser.h" 29 #include "host/commands/cvd/types.h" 30 31 namespace cuttlefish { 32 namespace selector { 33 34 /** 35 * This class parses the separated SelectorOptions defined in 36 * cvd_server.proto. 37 * 38 * Note that the parsing is from the perspective of syntax. 39 * 40 * In other words, this does not check the following, for example: 41 * 1. If the numeric instance id is duplicated 42 * 2. If the group name is already taken 43 * 44 * How it works is, it parses the selector options that are common 45 * across operations with SelectorCommonParser first. Following that, 46 * StartSelectorParser parses start-specific selector options. 47 */ 48 class StartSelectorParser { 49 public: 50 static Result<StartSelectorParser> ConductSelectFlagsParser( 51 const uid_t uid, const cvd_common::Args& selector_args, 52 const cvd_common::Args& cmd_args, const cvd_common::Envs& envs); 53 std::optional<std::string> GroupName() const; 54 std::optional<std::vector<std::string>> PerInstanceNames() const; InstanceIds()55 const std::optional<std::vector<unsigned>>& InstanceIds() const { 56 return instance_ids_; 57 } RequestedNumInstances()58 unsigned RequestedNumInstances() const { return requested_num_instances_; } IsMaybeDefaultGroup()59 bool IsMaybeDefaultGroup() const { return may_be_default_group_; } MustAcquireFileLock()60 bool MustAcquireFileLock() const { return must_acquire_file_lock_; } 61 62 private: 63 StartSelectorParser(const std::string& system_wide_user_home, 64 const cvd_common::Args& selector_args, 65 const cvd_common::Args& cmd_args, 66 const cvd_common::Envs& envs, 67 SelectorCommonParser&& common_parser); 68 69 Result<void> ParseOptions(); 70 71 struct InstanceIdsParams { 72 std::optional<std::string> num_instances; 73 std::optional<std::string> instance_nums; 74 std::optional<std::string> base_instance_num; 75 std::optional<unsigned> cuttlefish_instance_env; 76 std::optional<unsigned> vsoc_suffix; 77 }; 78 79 class ParsedInstanceIdsOpt { 80 friend class StartSelectorParser; 81 82 private: ParsedInstanceIdsOpt(const std::vector<unsigned> & instance_ids)83 ParsedInstanceIdsOpt(const std::vector<unsigned>& instance_ids) 84 : instance_ids_{instance_ids}, 85 n_instances_{static_cast<unsigned>(instance_ids.size())} {} ParsedInstanceIdsOpt(const unsigned n_instances)86 ParsedInstanceIdsOpt(const unsigned n_instances) 87 : instance_ids_{std::nullopt}, n_instances_{n_instances} {} GetInstanceIds()88 auto GetInstanceIds() { return std::move(instance_ids_); } GetNumOfInstances()89 unsigned GetNumOfInstances() const { return n_instances_; } 90 std::optional<std::vector<unsigned>> instance_ids_; 91 const unsigned n_instances_; 92 }; 93 94 /* 95 * CF_ERR is meant to be an error: 96 * For example, --num_instances != |--instance_nums|. 97 * 98 * On the contrary, std::nullopt inside Result is not necessary one. 99 * std::nullopt inside Result means that with the given information, 100 * the instance_ids_ cannot be yet figured out, so the task is deferred 101 * to CreationAnaylizer or so, which has more contexts. For example, 102 * if no option at all is given, it is not an error; however, the 103 * StartSelectorParser alone cannot figure out the list of instance ids. The 104 * InstanceDatabase, UniqueResourceAllocator, InstanceLockFileManager will be 105 * involved to automatically generate the valid, numeric instance ids. 106 * If that's the case, Result{std::nullopt} could be returned. 107 * 108 */ 109 Result<ParsedInstanceIdsOpt> HandleInstanceIds( 110 const InstanceIdsParams& instance_id_params); 111 112 struct InstanceFromEnvParam { 113 std::optional<unsigned> cuttlefish_instance_env; 114 std::optional<unsigned> vsoc_suffix; 115 std::optional<unsigned> num_instances; 116 }; 117 std::optional<std::vector<unsigned>> InstanceFromEnvironment( 118 const InstanceFromEnvParam& params); 119 120 struct VerifyNumOfInstancesParam { 121 std::optional<std::string> num_instances_flag; 122 std::optional<std::vector<std::string>> instance_names; 123 std::optional<std::string> instance_nums_flag; 124 }; 125 126 Result<unsigned> VerifyNumOfInstances( 127 const VerifyNumOfInstancesParam& params, 128 const unsigned default_n_instances = 1) const; 129 Result<bool> CalcMayBeDefaultGroup(); 130 Result<bool> CalcAcquireFileLock(); 131 132 struct WebrtcCalculatedNames { 133 std::optional<std::string> group_name; 134 std::optional<std::vector<std::string>> per_instance_names; 135 }; 136 Result<WebrtcCalculatedNames> CalcNamesUsingWebrtcDeviceId(); 137 138 /** 139 * The following are considered, and left empty if can't be figured out. 140 * 141 * --base_instance_num, --instance_nums, --num_instances, 142 * instance_names_.size(), CUTTLEFISH_INSTANCE, and vsoc-suffix if 143 * it is the user name. 144 * 145 * instance_names_.size() is effectively another --num_instances. 146 * CUTTLEFISH_INSTANCE and the suffix in order are considered as 147 * --base_instance_num if --base_instance_num is not given and 148 * --instance_nums is not given. 149 * 150 */ 151 std::optional<std::vector<unsigned>> instance_ids_; 152 unsigned requested_num_instances_; 153 bool may_be_default_group_; 154 bool must_acquire_file_lock_; 155 std::optional<std::string> group_name_; 156 std::optional<std::vector<std::string>> per_instance_names_; 157 158 // temporarily keeps the leftover of the input cmd_args 159 const std::string client_user_home_; 160 cvd_common::Args selector_args_; 161 cvd_common::Args cmd_args_; 162 cvd_common::Envs envs_; 163 SelectorCommonParser common_parser_; 164 }; 165 166 } // namespace selector 167 } // namespace cuttlefish 168