| // Copyright 2022 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use std::env; |
| use std::path::Path; |
| use std::process::exit; |
| |
| use hwsec_utils::context::RealContext; |
| use hwsec_utils::error::HwsecError; |
| use hwsec_utils::gsc::gsc_update; |
| use libchromeos::syslog; |
| use log::error; |
| |
| static STDERR_LOGGER: StderrLogger = StderrLogger; |
| |
| struct StderrLogger; |
| |
| impl log::Log for StderrLogger { |
| fn enabled(&self, _metadata: &log::Metadata) -> bool { |
| true |
| } |
| fn log(&self, record: &log::Record) { |
| eprintln!("{} - {}", record.level(), record.args()); |
| } |
| fn flush(&self) {} |
| } |
| |
| // The first argument is the root path of the ChromeOS image. |
| // We will use the GCS image under that path to update the GSC. |
| pub fn parse_args(args: Vec<&str>) -> Option<&Path> { |
| if args.len() <= 1 { |
| return Some(Path::new("/")); |
| } |
| |
| let root = Path::new(args[1]); |
| if !root.is_dir() { |
| error!("The root `{}` does not exist.", root.display()); |
| return None; |
| } |
| Some(root) |
| } |
| |
| // This script is run at postinstall phase of Chrome OS installation process. |
| // It checks if the currently running GSC image is ready to accept a |
| // background update and if the resident trunks_send utility is capable of |
| // updating the GSC. If any of the checks fails, the script exits, otherwise it |
| // tries updating the H1 with the new GSC image. |
| fn main() { |
| let args_string: Vec<String> = env::args().collect(); |
| let args: Vec<&str> = args_string.iter().map(|s| s.as_str()).collect(); |
| |
| let ident = match syslog::get_ident_from_process() { |
| Some(ident) => ident, |
| None => std::process::exit(1), |
| }; |
| |
| if let Err(e) = syslog::init(ident, true /* Log to stderr */) { |
| eprintln!("failed to initialize syslog: {}", e); |
| // Fallback to the std error logger. |
| log::set_logger(&STDERR_LOGGER).unwrap(); |
| log::set_max_level(log::LevelFilter::Info); |
| } |
| |
| let Some(root) = parse_args(args) else { |
| error!("Failed to parse root from args."); |
| exit(1); |
| }; |
| |
| let mut real_ctx = RealContext::new(); |
| match gsc_update(&mut real_ctx, root) { |
| Ok(()) => std::process::exit(0), |
| Err(hwsec_error) => match hwsec_error { |
| HwsecError::GsctoolError(err_code) => std::process::exit(err_code), |
| _ => std::process::exit(-1), |
| }, |
| } |
| } |