1 # 2 # Copyright (C) 2018 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 import datetime 18 import os 19 import tempfile 20 import zipfile 21 22 from host_controller import common 23 from host_controller.command_processor import base_command_processor 24 from host_controller.utils.gsi import img_utils 25 26 from vts.utils.python.common import cmd_utils 27 28 29 class CommandGsispl(base_command_processor.BaseCommandProcessor): 30 """Command processor for gsispl command. 31 32 Attributes: 33 arg_parser: ConsoleArgumentParser object, argument parser. 34 console: cmd.Cmd console object. 35 command: string, command name which this processor will handle. 36 command_detail: string, detailed explanation for the command. 37 """ 38 39 command = "gsispl" 40 command_detail = "Changes security patch level on a selected GSI file." 41 42 # @Override 43 def SetUp(self): 44 """Initializes the parser for device command.""" 45 self.arg_parser.add_argument( 46 "--gsi", 47 help="Path to GSI image to change security patch level. " 48 "If path is not given, the most recently fetched system.img " 49 "kept in device_image_info dictionary is used and then " 50 "device_image_info will be updated with the new GSI file.") 51 self.arg_parser.add_argument( 52 "--version", help="New version ID. It should be YYYY-mm-dd format") 53 self.arg_parser.add_argument( 54 "--version_from_path", 55 help="Path to vendor provided image file to retrieve SPL version. " 56 "If just a file name is given, the most recently fetched .img " 57 "file will be used.") 58 59 # @Override 60 def Run(self, arg_line): 61 """Changes security patch level on a selected GSI file.""" 62 args = self.arg_parser.ParseLine(arg_line) 63 if args.gsi: 64 if os.path.isfile(args.gsi): 65 gsi_path = args.gsi 66 else: 67 print "Cannot find system image in given path" 68 return 69 elif "system.img" in self.console.device_image_info: 70 gsi_path = self.console.device_image_info["system.img"] 71 else: 72 print "Cannot find system image." 73 return False 74 75 if args.version: 76 try: 77 version_date = datetime.datetime.strptime( 78 args.version, "%Y-%m-%d") 79 version = "{:04d}-{:02d}-{:02d}".format( 80 version_date.year, version_date.month, version_date.day) 81 except ValueError as e: 82 print "version ID should be YYYY-mm-dd format." 83 return 84 elif args.version_from_path: 85 if os.path.isabs(args.version_from_path) and os.path.exists( 86 args.version_from_path): 87 img_path = args.version_from_path 88 elif args.version_from_path in self.console.device_image_info: 89 img_path = self.console.device_image_info[ 90 args.version_from_path] 91 elif (args.version_from_path == "boot.img" 92 and "full-zipfile" in self.console.device_image_info): 93 tempdir_base = os.path.join(os.getcwd(), "tmp") 94 if not os.path.exists(tempdir_base): 95 os.mkdir(tempdir_base) 96 dest_path = tempfile.mkdtemp(dir=tempdir_base) 97 98 with zipfile.ZipFile( 99 self.console.device_image_info["full-zipfile"], 100 'r') as zip_ref: 101 zip_ref.extractall(dest_path) 102 img_path = os.path.join(dest_path, "boot.img") 103 else: 104 print("Cannot find %s file." % args.version_from_path) 105 return False 106 107 version_dict = img_utils.GetSPLVersionFromBootImg(img_path) 108 if "year" in version_dict and "month" in version_dict: 109 version = "{:04d}-{:02d}-{:02d}".format( 110 version_dict["year"], version_dict["month"], 111 common._SPL_DEFAULT_DAY) 112 else: 113 print("Failed to fetch SPL version from %s file." % img_path) 114 return False 115 else: 116 print("version ID or path of .img file must be given.") 117 return False 118 119 output_path = os.path.join( 120 os.path.dirname(os.path.abspath(gsi_path)), 121 "system-{}.img".format(version)) 122 stdout, _, err_code = cmd_utils.ExecuteOneShellCommand( 123 "{} {} {} {}".format( 124 os.path.join(os.getcwd(), "host_controller", "gsi", 125 "change_security_patch_ver.sh"), gsi_path, 126 output_path, version)) 127 if err_code is 0: 128 if not args.gsi: 129 print("system.img path is updated to : {}".format(output_path)) 130 self.console.device_image_info["system.img"] = output_path 131 else: 132 print "gsispl error: {}".format(stdout) 133 return False 134