def test_neither_url_or_dynurl(self, tmpdir): ''''! Test case when there is neither "url" or "dynamic-url" for a pre-check script ''' d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "remove": { "version": "SONiC-OS-int_odm_hwq_sonic_v201811.0-bc110ac", "pre-check": { "abc": { "source": "http://localhost:2000/content/ztp/firmware_check.sh" } } }, "halt-on-failure": false, "ignore-result": false, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 21:16:23" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def test_remove_no_image_given(self, tmpdir): ''''! Test case when there is no "image" with "remove" action ''' d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "remove": { "XXversion": "SONiC-OS-int_odm_hwq_sonic_v201811.0-bc110ac" }, "halt-on-failure": false, "ignore-result": false, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 21:16:23" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def test_download_image_nfound(self, tmpdir): '''! Test case when "install" option not able to download the image file ''' d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "halt-on-failure": false, "ignore-result": false, "install": { "url": { "source": "http://localhost:2000/content/ztp/SONiC.int_odm_hwq_sonic_v201811.0-bc110ac.bin" } }, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 00:34:10" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def test_remove_image_failed(self, tmpdir): ''''! Test case when removing a SONiC image fail ''' content = """#!/bin/sh exit 0 """ self.__write_file("/tmp/test_firmware.txt", content) d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "remove": { "version": "SONiC-OS-int_odm_hwq_sonic_v201811.0-bc110ac" }, "halt-on-failure": false, "ignore-result": false, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 21:16:23" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def test_remove_image_nexist_also_install_case2(self, tmpdir): ''''! Test when the image given with "remove" option does not exist, and there is also an "install" option in the json file ''' d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "remove": { "version": "foo" }, "install": { "url": { "source": "file:///abc/xyz/foo" } }, "halt-on-failure": false, "ignore-result": false, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 21:16:23" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def test_remove_pre_check_failed(self, tmpdir): ''''! Test case when the pre-check script is failing on "Remove" action ''' content = """#!/bin/sh exit 1 """ self.__write_file("/tmp/test_firmware.txt", content) d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "remove": { "version": "SONiC-OS-int_odm_hwq_sonic_v201811.0-bc110ac", "pre-check": { "url": { "destination": "/tmp/firmware_check.sh", "source": "file:///tmp/test_firmware.txt" } } }, "halt-on-failure": false, "ignore-result": false, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 21:16:23" } } """) firmware = Firmware(str(fh)) firmware.main()
def test_download_image_found_but_invalid(self, tmpdir): '''! Test case when plugin "install" option not able to download the image file ''' content = """ Foo """ self.__write_file("/tmp/test_firmware.txt", content) d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "halt-on-failure": false, "ignore-result": false, "install": { "url": { "source": "file:///tmp/test_firmware.txt" } }, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 00:34:10" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def add_firmware(firm): """add firmware from info file""" ports = firm['devices'] path = Path(firm['path']).parent versions = [] updated_firm = firm.copy() for p in ports: fware = Firmware(port=p, firmware_info=firm) licenses = firm.get('licenses', []) for file in licenses: repo, file_path = file.split(':') fware.retrieve_license(path, repository=repo, repo_path=file_path) compat = fware.get_compatible_tags() for cmp in compat: prev_compat = next( (v for v in versions if v['version'] == cmp['version']), None) if prev_compat: always_merger.merge(prev_compat, cmp) else: versions.append(cmp) updated_firm['versions'] = versions for vers in versions: devices = vers.get('devices') if len(vers['devices']) >= 0: v_dir = path / vers['git_tag'] dev_dirs = [Path(v_dir / dev) for dev in devices] [d.mkdir(exist_ok=True, parents=True) for d in dev_dirs] new = update_file(firm, updated_firm) fware_index = INFO['firmware'].index(firm) INFO['firmware'].pop(fware_index) INFO['firmware'].append(new) return new
def test_data_input_case3(self, tmpdir): ''''! Test case of an incorrect json data input: parameter "container-name" needs to be specified ''' d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "upgrade-docker": { "cleanup-image": false, "enforce-check": true, "url": { "source": "http://localhost:2000/content/ztp/docker-snmp-sv2.gz" } }, "halt-on-failure": false, "ignore-result": false, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 19:34:39" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def test_data_input_case2(self, tmpdir): ''''! Test case of an incorrect json data input: parameter of wrong type ''' d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "install": { "set-default": 123, "set-next-boot": true, "url": { "source": "http://localhost:2000/content/ztp/SONiC.int_odm_hwq_sonic_v201811.0-bc110ac.bin" } }, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 19:01:25" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def test_install_image_dynurl(self, tmpdir): ''''! Test case when the install SONiC image can not be found using a dynamic URL ''' d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "halt-on-failure": false, "ignore-result": false, "install": { "set-default": false, "set-next-boot": true, "dynamic-url" : { "source" : { "prefix" : "file:///abc/xyz/foo", "identifier" : "hostname", "suffix" : ".json" } } }, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 21:36:15" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def test_no_section(self, tmpdir): ''''! Test case when there is no section in the json input data ''' d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def post(self): devName = self.request.get("deviceName") device_query = Device.all().filter("name = ", devName) devItem = device_query.fetch(1)[0] fwgName = self.request.get("fwgName") fw_query = FirmwareGroup.all().filter("name = ", fwgName) fwgItem = fw_query.fetch(1)[0] releaseNumber = self.request.get("releaseName") relQuery = Firmware.all().filter("group = ", fwgItem).filter("version = ", releaseNumber) relItem = relQuery.fetch(1)[0] installationTime = self.request.get("releaseDate") if installationTime.strip().lower() == "now": installationTime = None else: installationTime = datetime.strptime(installationTime, "%Y-%m-%d") gUser = users.get_current_user() query = User.all().filter("googleUser = ", gUser) res = query.fetch(1) myUser = res[0] udu = UserDeviceUpdates() udu.user = myUser udu.device = devItem udu.release = relItem if installationTime: udu.updateDatetime = installationTime udu.put()
def test_install_image_with_dynurl(self, tmpdir): ''''! Test case to install a new image using a dyamic URL ''' content = """#!/bin/sh exit 0 """ self.__write_file("/tmp/test_firmware.txt", content) d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "halt-on-failure": false, "ignore-result": false, "install": { "pre-check": { "dynamic-url" : { "source" : { "prefix" : "file:///tmp/test_firmware.txt", "identifier" : "hostname", "suffix" : ".json" } } }, "set-default": false, "set-next-boot": true, "url": { "source": "http://localhost:2000/content/ztp/SONiC.int_odm_hwq_sonic_v201811.0-bc110ac.bin" } }, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 21:36:15" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def Ztest_upgrade_docker_failed_enforced_case2(self, tmpdir): ''''! Test case when the 'upgrade'docker' operation is failing with enforcing the check ''' content = """#!/bin/sh exit 0 """ http = HttpServer() d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "upgrade-docker": { "container-name" : "snmp", "dynamic-url" : { "source" : { "prefix" : "http://localhost:2000/ztp/json/ztp_", "identifier" : "hostname", "suffix" : ".json" } }, "cleanup-image": true, "enforce-check" : true, "tag" : "foo" }, "halt-on-failure": false, "ignore-result": false, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 21:16:23" } } """) http.start(text=content) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 http.stop()
def test_upgrade_docker_pre_check_failed_case2(self, tmpdir): ''''! Test case when the pre-check script does not include either "url" or "dynamic-url" ''' content = """#!/bin/sh exit 0 """ self.__write_file("/tmp/test_firmware.txt", content) d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "upgrade-docker": { "pre-check": { "dynamic-url" : { "source" : { "prefix" : "file:///tmp/test_firmware.txt", "identifier" : "hostname", "suffix" : ".json" } } }, "container-name" : "snmp", "cleanup-image": true, "enforce-check" : false }, "halt-on-failure": false, "ignore-result": false, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 21:16:23" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def extract_parser_handler(args): print("Extracting wavetables from {} to {}".format( args.firmware, os.path.abspath(args.out_wav_dir))) firmware = Firmware.load_from_mff(args.firmware) if args.verbose: firmware.log() wavetables_image = firmware.get_image(FirmwareImage.Type.WAVETABLES) wavetables = Wavetables.from_image(wavetables_image) mkdir_p(args.out_wav_dir) wavetables.write_tables_to_wavs(args.out_wav_dir)
def test_binary_version(self, tmpdir): ''''! Test the functions __which_current_image and __binary_version ''' content = """#!/bin/sh exit 0 """ self.__write_file("/tmp/test_firmware", content) d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "halt-on-failure": false, "ignore-result": false, "install": { "url": { "source": "file:///tmp/test_firmware" } }, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 00:34:10" } } """) firmware = Firmware(str(fh)) current_image = firmware._Firmware__which_current_image() assert (current_image != '') v = firmware._Firmware__binary_version("foo") assert (v == '') v = firmware._Firmware__binary_version(current_image) assert (v == '') with pytest.raises(SystemExit) as pytest_wrapped_e: firmware._Firmware__set_default_image('Foo') assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1 with pytest.raises(SystemExit) as pytest_wrapped_e: firmware._Firmware__set_next_boot_image('Foo') assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def replace_parser_handler(args): print( "Replacing wavetables from {} with those in {} and writing result to {}". format( args.firmware, os.path.abspath(args.wav_dir), os.path.abspath(args.out_firmware))) firmware = Firmware.load_from_mff(args.firmware) wavetables = Wavetables.from_image(firmware.get_image(FirmwareImage.Type.WAVETABLES)) wavetables.replace_tables_with_wavs(args.wav_dir) firmware.put_image(wavetables.to_image()) if args.verbose: firmware.log() firmware.write_to_mff(args.out_firmware) # Sanity check that the file was written. assert(Firmware.load_from_mff(args.out_firmware) is not None)
def test_data_input_case5(self, tmpdir): ''''! Test case when the image file does not include neither a URL or a dynamic URL ''' content = """#!/bin/sh exit 0 """ self.__write_file("/tmp/test_firmware.txt", content) d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "install": { "pre-check": { "url": { "source": "file:///tmp/test_firmware.txt", "destination": "/tmp/firmware_check.sh" } }, "set-default": false, "set-next-boot": true, "Xurl": { "source": "http://localhost:2001/content/ztp/SONiC.int_odm_hwq_sonic_v201811.0-bc110ac.bin" } }, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 19:01:25" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def test_data_input_case4(self, tmpdir): ''''! Test case of pre-check script returning an error Exec format error] encountered while processing the pre-check command ''' content = """ #!/bin/sh exit 1 """ self.__write_file("/tmp/test_firmware.txt", content) d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "install": { "pre-check": { "url": { "source": "file:///tmp/test_firmware.txt", "destination": "/tmp/firmware_check.sh" } }, "set-default": false, "set-next-boot": true, "Xurl": { "source": "http://localhost:2001/content/ztp/SONiC.int_odm_hwq_sonic_v201811.0-bc110ac.bin" } }, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 19:01:25" } } """) firmware = Firmware(str(fh)) firmware.main()
def test_upgrade_docker_failed(self, tmpdir): ''''! Test case when the upgrade docker fails ''' content = """#!/bin/sh exit 0 """ self.__write_file("/tmp/test_firmware.txt", content) d = tmpdir.mkdir("valid") fh = d.join("input.json") fh.write(""" { "01-firmware": { "upgrade-docker": { "container-name" : "foo", "url": { "source": "file:///tmp/test_firmware.txt" }, "cleanup-image": false, "enforce-check" : true }, "halt-on-failure": false, "ignore-result": false, "plugin": "firmware", "reboot-on-failure": false, "reboot-on-success": false, "status": "BOOT", "timestamp": "2019-04-25 21:16:23" } } """) firmware = Firmware(str(fh)) with pytest.raises(SystemExit) as pytest_wrapped_e: firmware.main() assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 1
def _parse_entry_table(self) -> (List[Firmware], List[Directory]): entries = chunker(self.firmware_entry_table[4:], 4) for index, entry in enumerate(entries): firmware_type = self._FIRMWARE_ENTRY_TYPES[index] if index < len( self._FIRMWARE_ENTRY_TYPES) else 'unknown' address = struct.unpack('<I', entry)[0] & 0x00FFFFFF # assumption: offset == 0 is an invalid entry if address not in [0x0, 0xfffffe]: directory = self[address:address + 16 * 8] magic = directory[:4] # either this entry points to a PSP directory directly if magic in [b'$PSP', b'$BHD']: directory = Directory(self, address, firmware_type) self.directories.append(directory) # if this Directory points to a secondary directory: add it, too if directory.secondary_directory_address is not None: secondary_directory = Directory( self, directory.secondary_directory_address, 'secondary') self.directories.append(secondary_directory) # or this entry points to a combo-directory (i.e. two directories) elif magic == b'2PSP': psp_dir_one_addr = struct.unpack( '<I', directory[10 * 4:10 * 4 + 4])[0] & 0x00FFFFFF psp_dir_two_addr = struct.unpack( '<I', directory[14 * 4:14 * 4 + 4])[0] & 0x00FFFFFF for address in [psp_dir_one_addr, psp_dir_two_addr]: directory = Directory(self, address, firmware_type) self.directories.append(directory) # if this Directory points to a secondary directory: add it, too if directory.secondary_directory_address is not None: secondary_directory = Directory( self, directory.secondary_directory_address, 'secondary') self.directories.append(secondary_directory) # or this entry is unparsable and thus a firmware else: firmware = Firmware(self, address, firmware_type, magic) self.firmwares.append(firmware)
def add_device(device): """add device from info file""" fware_info = get_firm_by_device(device) dev_fware = device['firmware'] # Find a suitable port _port_attrs = ['machine', 'sysname', 'nodename'] _port_ids = [dev_fware.get(a).lower().split() for a in _port_attrs] port_ids = set(chain.from_iterable(_port_ids)) fware_devs = [d.lower() for d in fware_info['devices']] port = list(set(fware_devs).intersection(port_ids))[0] fware_tag = dev_fware['version'] fware_versions = [v['version'] for v in fware_info['versions']] if fware_tag not in fware_versions: try: fware_tag = fware_versions[0] except IndexError: fware_tag = "master" fware = Firmware(firmware_info=fware_info, port=port, tag=fware_tag) device_root = Path(device['path']).parent mods_out = device_root / 'frozen' with file_backups(mods_out, "*.py"): mods_out.mkdir(exist_ok=True, parents=True) fware.retrieve_license(device_root) mod_paths = fware_info['module_path'] if isinstance(mod_paths, list) and any( (i for i in mod_paths if '@' in i)): for mod_path in mod_paths: out_append, repo_path = mod_path.split('@') submod_out = mods_out / out_append / repo_path mods_out.mkdir(exist_ok=True, parents=True) fware.module_path = [Path(repo_path)] fware.retrieve_modules(submod_out) else: fware.retrieve_modules(mods_out) make_stubs(mods_out) return device
"--%icode" % i, help="file containing code to be added to %i (%X) section" % (i, i)) parser.add_argument( "--%irst" % i, help="file containing label->address mapping for the %i. (%X) " "section" % (i, i)) args = parser.parse_args() #check firmware image if not check_firmware_image(args.firmware): logger.warning("This firmware version is not verified for this " "patches.") fw = Firmware() fw.load_from_file(args.firmware) if args.action == actions[1]: # "FindFreeBlock" if args.section is None: logger.error("No section provided") else: fw.save_last_free_chunk(section_names.index(args.section), args.output) if args.action == actions[0]: # "GenerateHFile" fw.generate_header_file(args.output) if args.action == actions[2]:
def get(self): gUser = users.get_current_user() query = User.all().filter("googleUser = "******"user = "******"sEcho") numberRecords = int(self.request.get("iDisplayLength")) startRecords = int(self.request.get("iDisplayStart")) try: indexSort = int(self.request.get("iSortCol_0")) except: indexSort = 0 directionSort = self.request.get("sSortDir_0") if directionSort.strip().lower() == "desc": directionSort = "-" else: directionSort = "" # sortList = ['device.name','device.manufactorer'] # device_query = device_query.order(directionSort + sortList[indexSort]) i = 0 devices = device_query.fetch(numberRecords, offset=startRecords) txt = ( '{"sEcho": ' + sEcho + ', "iTotalRecords": ' + str(nrDevices) + ', "iTotalDisplayRecords": ' + str(nrDevices) + ', "aaData": [' ) for device in devices: fws = 0 if i: txt += "," if device.firmwareGroup: fwgName = device.firmwareGroup.name fwQuery = Firmware.all().filter("group =", device.firmwareGroup).order("-releaseDate") fws = fwQuery.fetch(1) if fws: fws = fws[0] fwgLatest = str(fws.version) + " (" + str(fws.releaseDate) + ")" else: fwgLatest = "n.a." else: fwgName = "n.a." fwgLatest = "n.a." releaseQuery = ( UserDeviceUpdates.all() .filter("user = "******"device = ", device.device) .order("-updateDatetime") ) releases = releaseQuery.fetch(1) if releases: relName = releases[0].release.version relDate = str(releases[0].updateDatetime) else: relName = "n.a." relDate = "n.a." txt += ( '["' + device.device.name + '","' + device.device.manufactorer.name + '","' + fwgName + '","' + relName + '","' + relDate + '","' + fwgLatest + '"' ) # newer firmware available? if fws: if not releases: txt += ', "1"]' elif releases[0].release.version != fws.version: txt += ', "1"]' else: txt += ', "0"]' else: txt += ', "0"]' i += 1 txt += "]}" self.response.out.write(txt)
# we do it this way to be compatible to Psychson parser.add_argument("--basecode", help="file containing code to be added to base section") parser.add_argument("--baserst", help="file containing label->address mapping for the base section") for i in xrange(16): parser.add_argument("--%icode" % i, help="file containing code to be added to %i (%X) section" % (i, i)) parser.add_argument( "--%irst" % i, help="file containing label->address mapping for the %i. (%X) " "section" % (i, i) ) args = parser.parse_args() # check firmware image if not check_firmware_image(args.firmware): logger.warning("This firmware version is not verified for this " "patches.") fw = Firmware() fw.load_from_file(args.firmware) if args.action == actions[1]: # "FindFreeBlock" if args.section is None: logger.error("No section provided") else: fw.save_last_free_chunk(section_names.index(args.section), args.output) if args.action == actions[0]: # "GenerateHFile" fw.generate_header_file(args.output) if args.action == actions[2]: # "ApplyPatches"