| 1228 | } |
| 1229 | |
| 1230 | std::optional<proc::proc_t> parse(const std::string &file_name) { |
| 1231 | |
| 1232 | // Prepare environment variables. |
| 1233 | auto this_env = boost::this_process::environment(); |
| 1234 | |
| 1235 | std::set<std::string> ids; |
| 1236 | std::vector<proc::ctx_t> apps; |
| 1237 | int i = 0; |
| 1238 | |
| 1239 | size_t fail_count = 0; |
| 1240 | do { |
| 1241 | // Read the JSON file into a tree. |
| 1242 | nlohmann::json tree; |
| 1243 | try { |
| 1244 | std::string content = file_handler::read_file(file_name.c_str()); |
| 1245 | tree = nlohmann::json::parse(content); |
| 1246 | } catch (const std::exception& e) { |
| 1247 | BOOST_LOG(warning) << "Couldn't read apps.json properly! Apps will not be loaded."sv; |
| 1248 | break; |
| 1249 | } |
| 1250 | |
| 1251 | try { |
| 1252 | migrate(tree, file_name); |
| 1253 | |
| 1254 | if (tree.contains("env") && tree["env"].is_object()) { |
| 1255 | for (auto &item : tree["env"].items()) { |
| 1256 | this_env[item.key()] = parse_env_val(this_env, item.value().get<std::string>()); |
| 1257 | } |
| 1258 | } |
| 1259 | |
| 1260 | // Ensure the "apps" array exists. |
| 1261 | if (!tree.contains("apps") || !tree["apps"].is_array()) { |
| 1262 | BOOST_LOG(warning) << "No apps were defined in apps.json!!!"sv; |
| 1263 | break; |
| 1264 | } |
| 1265 | |
| 1266 | // Iterate over each application in the "apps" array. |
| 1267 | for (auto &app_node : tree["apps"]) { |
| 1268 | proc::ctx_t ctx; |
| 1269 | ctx.idx = std::to_string(i); |
| 1270 | ctx.uuid = app_node.at("uuid"); |
| 1271 | |
| 1272 | // Build the list of preparation commands. |
| 1273 | std::vector<proc::cmd_t> prep_cmds; |
| 1274 | bool exclude_global_prep = app_node.value("exclude-global-prep-cmd", false); |
| 1275 | if (!exclude_global_prep) { |
| 1276 | prep_cmds.reserve(config::sunshine.prep_cmds.size()); |
| 1277 | for (auto &prep_cmd : config::sunshine.prep_cmds) { |
| 1278 | auto do_cmd = parse_env_val(this_env, prep_cmd.do_cmd); |
| 1279 | auto undo_cmd = parse_env_val(this_env, prep_cmd.undo_cmd); |
| 1280 | prep_cmds.emplace_back( |
| 1281 | std::move(do_cmd), |
| 1282 | std::move(undo_cmd), |
| 1283 | std::move(prep_cmd.elevated) |
| 1284 | ); |
| 1285 | } |
| 1286 | } |
| 1287 | if (app_node.contains("prep-cmd") && app_node["prep-cmd"].is_array()) { |