1 /** 2 * Copyright © 2019 IBM Corporation 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 #include "model.hpp" 17 #include "updater.hpp" 18 #include "utility.hpp" 19 #include "validator.hpp" 20 #include "version.hpp" 21 22 #include <CLI/CLI.hpp> 23 #include <phosphor-logging/lg2.hpp> 24 #include <sdbusplus/bus.hpp> 25 26 #include <cassert> 27 #include <filesystem> 28 29 int main(int argc, char** argv) 30 { 31 std::string psuPathVersion, psuPathModel; 32 std::vector<std::string> versions; 33 bool validateUpdate = false; 34 bool rawOutput = false; 35 std::vector<std::string> updateArguments; 36 37 CLI::App app{"PSU utils app for OpenBMC"}; 38 auto action = app.add_option_group("Action"); 39 action->add_option("-g,--get-version", psuPathVersion, 40 "Get PSU version from inventory path"); 41 action->add_option("-m,--get-model", psuPathModel, 42 "Get PSU model from inventory path"); 43 action->add_option("-c,--compare", versions, 44 "Compare and get the latest version"); 45 auto updateOpt = 46 action 47 ->add_option("-u,--update", updateArguments, 48 "Update PSU firmware, expecting two arguments: " 49 "<PSU inventory path> <image-dir>") 50 ->expected(2) 51 ->type_name("PSU_PATH IMAGE_DIR"); 52 app.add_flag( 53 "--validate", validateUpdate, 54 "Validate number of present PSU vs number of required PSUs and all PSUs have same model before updating firmware") 55 ->needs(updateOpt); 56 action->require_option(1); // Only one option is supported 57 app.add_flag("--raw", rawOutput, "Output raw text without linefeed"); 58 CLI11_PARSE(app, argc, argv); 59 60 std::string ret; 61 62 auto bus = sdbusplus::bus::new_default(); 63 if (!psuPathVersion.empty()) 64 { 65 ret = version::getVersion(bus, psuPathVersion); 66 } 67 if (!psuPathModel.empty()) 68 { 69 ret = model::getModel(bus, psuPathModel); 70 } 71 if (!versions.empty()) 72 { 73 ret = version::getLatest(versions); 74 } 75 if (!updateArguments.empty()) 76 { 77 assert(updateArguments.size() == 2); 78 bool updateStatus = false; 79 if (validateUpdate) 80 { 81 updateStatus = updater::validateAndUpdate(bus, updateArguments[0], 82 updateArguments[1]); 83 } 84 else 85 { 86 updateStatus = 87 updater::update(bus, updateArguments[0], updateArguments[1]); 88 } 89 if (updateStatus) 90 { 91 ret = "Update successful"; 92 lg2::info("Successful update to PSU: {PSU}", "PSU", 93 updateArguments[0]); 94 } 95 else 96 { 97 lg2::error("Failed to update PSU: {PSU}", "PSU", 98 updateArguments[0]); 99 } 100 } 101 102 printf("%s", ret.c_str()); 103 if (!rawOutput) 104 { 105 printf("\n"); 106 } 107 return ret.empty() ? 1 : 0; 108 } 109