mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-04 01:04:43 +00:00
Use black to format python source in a consistent manner
No code changes.
This commit is contained in:
parent
39dc902a42
commit
fe11927eef
@ -6,6 +6,7 @@ import sys
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Run afl-fuzz on all cores')
|
||||
parser.add_argument('--input', '-i', help='fuzzing input directory')
|
||||
@ -26,8 +27,17 @@ def main():
|
||||
|
||||
# run the main instance
|
||||
envp = None
|
||||
argv = ['afl-fuzz', '-m300', '-i', args.input, '-o', args.output,
|
||||
'-M', 'fuzzer00', args.path]
|
||||
argv = [
|
||||
'afl-fuzz',
|
||||
'-m300',
|
||||
'-i',
|
||||
args.input,
|
||||
'-o',
|
||||
args.output,
|
||||
'-M',
|
||||
'fuzzer00',
|
||||
args.path,
|
||||
]
|
||||
if args.command:
|
||||
argv.append(args.command)
|
||||
argv.append('@@')
|
||||
@ -37,8 +47,17 @@ def main():
|
||||
# run the secondary instances
|
||||
cs = []
|
||||
for i in range(1, os.cpu_count()):
|
||||
argv = ['afl-fuzz', '-m300', '-i', args.input, '-o', args.output,
|
||||
'-S', 'fuzzer%02i' % i, args.path]
|
||||
argv = [
|
||||
'afl-fuzz',
|
||||
'-m300',
|
||||
'-i',
|
||||
args.input,
|
||||
'-o',
|
||||
args.output,
|
||||
'-S',
|
||||
'fuzzer%02i' % i,
|
||||
args.path,
|
||||
]
|
||||
if args.command:
|
||||
argv.append(args.command)
|
||||
argv.append('@@')
|
||||
@ -54,5 +73,6 @@ def main():
|
||||
c.terminate()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
@ -4,68 +4,77 @@ import os
|
||||
import json
|
||||
import shutil
|
||||
|
||||
def prepare (target):
|
||||
#clone the flatpak json
|
||||
|
||||
def prepare(target):
|
||||
# clone the flatpak json
|
||||
cmd = ['git', 'submodule', 'update', '--remote', 'contrib/flatpak']
|
||||
subprocess.run (cmd, check=True)
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
#clone the submodules for that
|
||||
# clone the submodules for that
|
||||
cmd = ['git', 'submodule', 'update', '--init', '--remote', 'shared-modules/']
|
||||
subprocess.run (cmd, cwd='contrib/flatpak', check=True)
|
||||
subprocess.run(cmd, cwd='contrib/flatpak', check=True)
|
||||
|
||||
#parse json
|
||||
if os.path.isdir ('build'):
|
||||
shutil.rmtree ('build')
|
||||
# parse json
|
||||
if os.path.isdir('build'):
|
||||
shutil.rmtree('build')
|
||||
data = {}
|
||||
with open ('contrib/flatpak/org.freedesktop.fwupd.json', 'r') as rfd:
|
||||
data = json.load (rfd, strict=False)
|
||||
with open('contrib/flatpak/org.freedesktop.fwupd.json', 'r') as rfd:
|
||||
data = json.load(rfd, strict=False)
|
||||
platform = 'runtime/%s/x86_64/%s' % (data['runtime'], data['runtime-version'])
|
||||
sdk = 'runtime/%s/x86_64/%s' % (data['sdk'], data['runtime-version'])
|
||||
num_modules = len (data['modules'])
|
||||
num_modules = len(data['modules'])
|
||||
|
||||
#update to build from master
|
||||
# update to build from master
|
||||
data["branch"] = "master"
|
||||
for index in range(0, num_modules):
|
||||
module = data['modules'][index]
|
||||
if type (module) != dict or not 'name' in module:
|
||||
if type(module) != dict or not 'name' in module:
|
||||
continue
|
||||
name = module['name']
|
||||
if not 'fwupd' in name:
|
||||
continue
|
||||
data['modules'][index]['sources'][0].pop ('url')
|
||||
data['modules'][index]['sources'][0].pop ('sha256')
|
||||
data['modules'][index]['sources'][0].pop('url')
|
||||
data['modules'][index]['sources'][0].pop('sha256')
|
||||
data['modules'][index]['sources'][0]['type'] = 'dir'
|
||||
data['modules'][index]['sources'][0]['skip'] = [".git"]
|
||||
data['modules'][index]['sources'][0]['path'] = ".."
|
||||
|
||||
#write json
|
||||
# write json
|
||||
os.mkdir('build')
|
||||
with open (target, 'w') as wfd:
|
||||
with open(target, 'w') as wfd:
|
||||
json.dump(data, wfd, indent=4)
|
||||
os.symlink ('../contrib/flatpak/shared-modules','build/shared-modules')
|
||||
os.symlink('../contrib/flatpak/shared-modules', 'build/shared-modules')
|
||||
|
||||
# install the runtimes (parsed from json!)
|
||||
repo = 'flathub'
|
||||
repo_url = 'https://dl.flathub.org/repo/flathub.flatpakrepo'
|
||||
print ("Installing dependencies")
|
||||
print("Installing dependencies")
|
||||
cmd = ['flatpak', 'remote-add', '--if-not-exists', repo, repo_url]
|
||||
subprocess.run (cmd, check=True)
|
||||
subprocess.run(cmd, check=True)
|
||||
cmd = ['flatpak', 'install', '--assumeyes', repo, sdk]
|
||||
subprocess.run (cmd, check=True)
|
||||
subprocess.run(cmd, check=True)
|
||||
cmd = ['flatpak', 'install', '--assumeyes', repo, platform]
|
||||
subprocess.run (cmd, check=True)
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
|
||||
def build (target):
|
||||
cmd = ['flatpak-builder', '--repo=repo', '--force-clean', '--disable-rofiles-fuse', 'build-dir', target]
|
||||
subprocess.run (cmd, check=True)
|
||||
def build(target):
|
||||
cmd = [
|
||||
'flatpak-builder',
|
||||
'--repo=repo',
|
||||
'--force-clean',
|
||||
'--disable-rofiles-fuse',
|
||||
'build-dir',
|
||||
target,
|
||||
]
|
||||
subprocess.run(cmd, check=True)
|
||||
cmd = ['flatpak', 'build-bundle', 'repo', 'fwupd.flatpak', 'org.freedesktop.fwupd']
|
||||
subprocess.run (cmd, check=True)
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
t = os.path.join ('build', 'org.freedesktop.fwupd.json')
|
||||
prepare (t)
|
||||
build (t)
|
||||
t = os.path.join('build', 'org.freedesktop.fwupd.json')
|
||||
prepare(t)
|
||||
build(t)
|
||||
|
||||
# to run from the builddir:
|
||||
# sudo flatpak-builder --run build-dir org.freedesktop.fwupd.json /app/libexec/fwupd/fwupdtool get-devices
|
||||
|
@ -8,8 +8,9 @@ import os
|
||||
import sys
|
||||
import xml.etree.ElementTree as etree
|
||||
|
||||
|
||||
def parse_control_dependencies(requested_type):
|
||||
TARGET=os.getenv('OS')
|
||||
TARGET = os.getenv('OS')
|
||||
deps = []
|
||||
dep = ''
|
||||
|
||||
@ -25,11 +26,13 @@ def parse_control_dependencies(requested_type):
|
||||
SUBOS = split[1]
|
||||
else:
|
||||
import lsb_release
|
||||
|
||||
OS = lsb_release.get_distro_information()['ID'].lower()
|
||||
import platform
|
||||
|
||||
SUBOS = platform.machine()
|
||||
|
||||
tree = etree.parse(os.path.join(os.path.dirname (sys.argv[0]), "dependencies.xml"))
|
||||
tree = etree.parse(os.path.join(os.path.dirname(sys.argv[0]), "dependencies.xml"))
|
||||
root = tree.getroot()
|
||||
for child in root:
|
||||
if not "type" in child.attrib or not "id" in child.attrib:
|
||||
@ -80,6 +83,7 @@ def parse_control_dependencies(requested_type):
|
||||
deps.append(dep)
|
||||
return deps
|
||||
|
||||
|
||||
def update_debian_control(target):
|
||||
control_in = os.path.join(target, 'control.in')
|
||||
control_out = os.path.join(target, 'control')
|
||||
@ -102,7 +106,8 @@ def update_debian_control(target):
|
||||
else:
|
||||
wfd.write(line)
|
||||
|
||||
def update_debian_copyright (directory):
|
||||
|
||||
def update_debian_copyright(directory):
|
||||
copyright_in = os.path.join(directory, 'copyright.in')
|
||||
copyright_out = os.path.join(directory, 'copyright')
|
||||
|
||||
@ -114,13 +119,13 @@ def update_debian_copyright (directory):
|
||||
copyrights = []
|
||||
for root, dirs, files in os.walk('.'):
|
||||
for file in files:
|
||||
target = os.path.join (root, file)
|
||||
#skip translations and license file
|
||||
target = os.path.join(root, file)
|
||||
# skip translations and license file
|
||||
if target.startswith('./po/') or file == "COPYING":
|
||||
continue
|
||||
try:
|
||||
with open(target, 'r') as rfd:
|
||||
#read about the first few lines of the file only
|
||||
# read about the first few lines of the file only
|
||||
lines = rfd.readlines(220)
|
||||
except UnicodeDecodeError:
|
||||
continue
|
||||
@ -128,8 +133,10 @@ def update_debian_copyright (directory):
|
||||
continue
|
||||
for line in lines:
|
||||
if 'Copyright (C) ' in line:
|
||||
parts = line.split ('Copyright (C)')[1].strip() #split out the copyright header
|
||||
partition = parts.partition(' ')[2] # remove the year string
|
||||
parts = line.split('Copyright (C)')[
|
||||
1
|
||||
].strip() # split out the copyright header
|
||||
partition = parts.partition(' ')[2] # remove the year string
|
||||
copyrights += ["%s" % partition]
|
||||
copyrights = "\n\t ".join(sorted(set(copyrights)))
|
||||
with open(copyright_in, 'r') as rfd:
|
||||
@ -145,6 +152,7 @@ def update_debian_copyright (directory):
|
||||
else:
|
||||
wfd.write(line)
|
||||
|
||||
directory = os.path.join (os.getcwd(), 'debian')
|
||||
|
||||
directory = os.path.join(os.getcwd(), 'debian')
|
||||
update_debian_control(directory)
|
||||
update_debian_copyright(directory)
|
||||
|
@ -10,6 +10,7 @@ import sys
|
||||
import argparse
|
||||
import xml.etree.ElementTree as etree
|
||||
|
||||
|
||||
def parse_dependencies(OS, SUBOS, requested_type):
|
||||
deps = []
|
||||
dep = ''
|
||||
@ -39,24 +40,24 @@ def parse_dependencies(OS, SUBOS, requested_type):
|
||||
deps.append(dep)
|
||||
return deps
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
try:
|
||||
import distro
|
||||
|
||||
target = distro.linux_distribution()[0]
|
||||
except ModuleNotFoundError:
|
||||
target = None
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-o", "--os",
|
||||
default=target,
|
||||
choices=["fedora",
|
||||
"centos",
|
||||
"flatpak",
|
||||
"debian",
|
||||
"ubuntu",
|
||||
"arch"],
|
||||
help="dependencies for OS")
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--os",
|
||||
default=target,
|
||||
choices=["fedora", "centos", "flatpak", "debian", "ubuntu", "arch"],
|
||||
help="dependencies for OS",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
target = os.getenv('OS', args.os)
|
||||
|
@ -11,6 +11,7 @@ import tempfile
|
||||
import shutil
|
||||
from generate_dependencies import parse_dependencies
|
||||
|
||||
|
||||
def get_container_cmd():
|
||||
'''return docker or podman as container manager'''
|
||||
|
||||
@ -19,8 +20,9 @@ def get_container_cmd():
|
||||
if shutil.which('podman'):
|
||||
return 'podman'
|
||||
|
||||
|
||||
directory = os.path.dirname(sys.argv[0])
|
||||
TARGET=os.getenv('OS')
|
||||
TARGET = os.getenv('OS')
|
||||
|
||||
if TARGET is None:
|
||||
print("Missing OS environment variable")
|
||||
@ -58,19 +60,23 @@ with open(out.name, 'w') as wfd:
|
||||
wfd.write("RUN yum -y install \\\n")
|
||||
elif OS == "debian" or OS == "ubuntu":
|
||||
wfd.write("RUN apt update -qq && \\\n")
|
||||
wfd.write("\tDEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends\\\n")
|
||||
wfd.write(
|
||||
"\tDEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends\\\n"
|
||||
)
|
||||
elif OS == "arch":
|
||||
wfd.write("RUN pacman -Syu --noconfirm --needed\\\n")
|
||||
for i in range(0, len(deps)):
|
||||
if i < len(deps)-1:
|
||||
if i < len(deps) - 1:
|
||||
wfd.write("\t%s \\\n" % deps[i])
|
||||
else:
|
||||
wfd.write("\t%s \n" % deps[i])
|
||||
elif line == "%%%ARCH_SPECIFIC_COMMAND%%%\n":
|
||||
if OS == "debian" and SUBOS == "s390x":
|
||||
#add sources
|
||||
wfd.write('RUN cat /etc/apt/sources.list | sed "s/deb/deb-src/" >> /etc/apt/sources.list\n')
|
||||
#add new architecture
|
||||
# add sources
|
||||
wfd.write(
|
||||
'RUN cat /etc/apt/sources.list | sed "s/deb/deb-src/" >> /etc/apt/sources.list\n'
|
||||
)
|
||||
# add new architecture
|
||||
wfd.write('RUN dpkg --add-architecture %s\n' % SUBOS)
|
||||
elif line == "%%%OS%%%\n":
|
||||
wfd.write("ENV OS %s\n" % TARGET)
|
||||
@ -83,5 +89,5 @@ with open(out.name, 'w') as wfd:
|
||||
args += ['--build-arg=http_proxy=%s' % os.environ['http_proxy']]
|
||||
if 'https_proxy' in os.environ:
|
||||
args += ['--build-arg=https_proxy=%s' % os.environ['https_proxy']]
|
||||
args += [ "-f", "./%s" % os.path.basename(out.name), "."]
|
||||
args += ["-f", "./%s" % os.path.basename(out.name), "."]
|
||||
subprocess.check_call(args)
|
||||
|
@ -13,6 +13,7 @@ CAPSULE_FLAGS_PERSIST_ACROSS_RESET = 0x00010000
|
||||
CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE = 0x00020000
|
||||
CAPSULE_FLAGS_INITIATE_RESET = 0x00040000
|
||||
|
||||
|
||||
def add_header(infile, outfile, gd, fl=None):
|
||||
# parse GUID from command line
|
||||
try:
|
||||
@ -21,6 +22,7 @@ def add_header(infile, outfile, gd, fl=None):
|
||||
print(e)
|
||||
return 1
|
||||
import struct
|
||||
|
||||
try:
|
||||
with open(infile, 'rb') as f:
|
||||
bin_data = f.read()
|
||||
@ -45,7 +47,11 @@ def add_header(infile, outfile, gd, fl=None):
|
||||
bin_data = bin_data[hdrsz_old:]
|
||||
|
||||
# set header flags
|
||||
flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
|
||||
flags = (
|
||||
CAPSULE_FLAGS_PERSIST_ACROSS_RESET
|
||||
| CAPSULE_FLAGS_INITIATE_RESET
|
||||
| CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
|
||||
)
|
||||
if fl:
|
||||
flags = int(fl, 16)
|
||||
|
||||
@ -64,6 +70,7 @@ def add_header(infile, outfile, gd, fl=None):
|
||||
print('PayloadSz: 0x%04x' % imgsz)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Add capsule header on firmware')
|
||||
parser.add_argument('--guid', help='GUID of the device', required=True)
|
||||
|
@ -9,6 +9,7 @@ import struct
|
||||
import zlib
|
||||
import argparse
|
||||
|
||||
|
||||
def main(bin_fn, dfu_fn, pad, vid, pid, rev):
|
||||
|
||||
# read binary file
|
||||
@ -21,27 +22,32 @@ def main(bin_fn, dfu_fn, pad, vid, pid, rev):
|
||||
blob += b'\0'
|
||||
|
||||
# create DFU footer with checksum
|
||||
blob += struct.pack('<HHHH3sB',
|
||||
int(rev, 16), # version
|
||||
int(pid, 16), # PID
|
||||
int(vid, 16), # VID
|
||||
0x0100, # DFU version
|
||||
b'UFD', # signature
|
||||
0x10) # hdrlen
|
||||
crc32 = zlib.crc32(blob) ^ 0xffffffff
|
||||
blob += struct.pack(
|
||||
'<HHHH3sB',
|
||||
int(rev, 16), # version
|
||||
int(pid, 16), # PID
|
||||
int(vid, 16), # VID
|
||||
0x0100, # DFU version
|
||||
b'UFD', # signature
|
||||
0x10,
|
||||
) # hdrlen
|
||||
crc32 = zlib.crc32(blob) ^ 0xFFFFFFFF
|
||||
blob += struct.pack('<L', crc32)
|
||||
|
||||
# write binary file
|
||||
with open(dfu_fn, 'wb') as f:
|
||||
f.write(blob)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# parse args
|
||||
parser = argparse.ArgumentParser(description='Add DFU footer on firmware')
|
||||
parser.add_argument('--bin', help='Path to the .bin file', required=True)
|
||||
parser.add_argument('--dfu', help='Output DFU file path', required=True)
|
||||
parser.add_argument('--pad', help='Pad to a specific size, e.g. 0x4000', default=None)
|
||||
parser.add_argument(
|
||||
'--pad', help='Pad to a specific size, e.g. 0x4000', default=None
|
||||
)
|
||||
parser.add_argument('--vid', help='Vendor ID, e.g. 0x273f', required=True)
|
||||
parser.add_argument('--pid', help='Product ID, e.g. 0x1002', required=True)
|
||||
parser.add_argument('--rev', help='Revision, e.g. 0x1000', required=True)
|
||||
|
@ -21,6 +21,7 @@ def cd(path):
|
||||
yield
|
||||
os.chdir(prev_cwd)
|
||||
|
||||
|
||||
firmware_metainfo_template = """
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="firmware">
|
||||
@ -52,7 +53,9 @@ firmware_metainfo_template = """
|
||||
def make_firmware_metainfo(firmware_info, dst):
|
||||
local_info = vars(firmware_info)
|
||||
local_info["firmware_id"] = local_info["device_guid"][0:8]
|
||||
firmware_metainfo = firmware_metainfo_template.format(**local_info, timestamp=time.time())
|
||||
firmware_metainfo = firmware_metainfo_template.format(
|
||||
**local_info, timestamp=time.time()
|
||||
)
|
||||
|
||||
with open(os.path.join(dst, 'firmware.metainfo.xml'), 'w') as f:
|
||||
f.write(firmware_metainfo)
|
||||
@ -71,16 +74,22 @@ def get_firmware_bin(root, bin_path, dst):
|
||||
def create_firmware_cab(exe, folder):
|
||||
with cd(folder):
|
||||
if os.name == "nt":
|
||||
directive = os.path.join (folder, "directive")
|
||||
with open (directive, 'w') as wfd:
|
||||
wfd.write('.OPTION EXPLICIT\r\n')
|
||||
wfd.write('.Set CabinetNameTemplate=firmware.cab\r\n')
|
||||
wfd.write('.Set DiskDirectory1=.\r\n')
|
||||
wfd.write('firmware.bin\r\n')
|
||||
wfd.write('firmware.metainfo.xml\r\n')
|
||||
command = ['makecab.exe', '/f', directive]
|
||||
directive = os.path.join(folder, "directive")
|
||||
with open(directive, 'w') as wfd:
|
||||
wfd.write('.OPTION EXPLICIT\r\n')
|
||||
wfd.write('.Set CabinetNameTemplate=firmware.cab\r\n')
|
||||
wfd.write('.Set DiskDirectory1=.\r\n')
|
||||
wfd.write('firmware.bin\r\n')
|
||||
wfd.write('firmware.metainfo.xml\r\n')
|
||||
command = ['makecab.exe', '/f', directive]
|
||||
else:
|
||||
command = ['gcab', '--create', 'firmware.cab', 'firmware.bin', 'firmware.metainfo.xml']
|
||||
command = [
|
||||
'gcab',
|
||||
'--create',
|
||||
'firmware.cab',
|
||||
'firmware.bin',
|
||||
'firmware.metainfo.xml',
|
||||
]
|
||||
subprocess.check_call(command)
|
||||
|
||||
|
||||
@ -104,19 +113,50 @@ def main(args):
|
||||
print('Done')
|
||||
shutil.copy(os.path.join(dir, 'firmware.cab'), args.out)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Create fwupd packaged from windows executables')
|
||||
parser.add_argument('--firmware-name', help='Name of the firmware package can be customized (e.g. DellTBT)', required=True)
|
||||
parser.add_argument('--firmware-summary', help='One line description of the firmware package')
|
||||
parser.add_argument('--firmware-description', help='Longer description of the firmware package')
|
||||
parser.add_argument('--device-guid', help='GUID of the device this firmware will run on, this *must* match the output of one of the GUIDs in `fwupdmgr get-devices`', required=True)
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Create fwupd packaged from windows executables'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--firmware-name',
|
||||
help='Name of the firmware package can be customized (e.g. DellTBT)',
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--firmware-summary', help='One line description of the firmware package'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--firmware-description', help='Longer description of the firmware package'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--device-guid',
|
||||
help='GUID of the device this firmware will run on, this *must* match the output of one of the GUIDs in `fwupdmgr get-devices`',
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument('--firmware-homepage', help='Website for the firmware provider')
|
||||
parser.add_argument('--contact-info', help='Email address of the firmware developer')
|
||||
parser.add_argument('--developer-name', help='Name of the firmware developer', required=True)
|
||||
parser.add_argument('--release-version', help='Version number of the firmware package', required=True)
|
||||
parser.add_argument('--release-description', help='Description of the firmware release')
|
||||
parser.add_argument('--exe', help='(optional) Executable file to extract firmware from')
|
||||
parser.add_argument('--bin', help='Path to the .bin file (Relative if inside the executable; Absolute if outside) to use as the firmware image', required=True)
|
||||
parser.add_argument(
|
||||
'--contact-info', help='Email address of the firmware developer'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--developer-name', help='Name of the firmware developer', required=True
|
||||
)
|
||||
parser.add_argument(
|
||||
'--release-version',
|
||||
help='Version number of the firmware package',
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--release-description', help='Description of the firmware release'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--exe', help='(optional) Executable file to extract firmware from'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--bin',
|
||||
help='Path to the .bin file (Relative if inside the executable; Absolute if outside) to use as the firmware image',
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument('--out', help='Output cab file path', required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
|
@ -9,12 +9,14 @@ import os.path
|
||||
import sys
|
||||
import tempfile
|
||||
import gi
|
||||
|
||||
gi.require_version('Fwupd', '2.0')
|
||||
from gi.repository import Fwupd #pylint: disable=wrong-import-position
|
||||
from gi.repository import Fwupd # pylint: disable=wrong-import-position
|
||||
from simple_client import install, check_exists
|
||||
from add_capsule_header import add_header
|
||||
from firmware_packager import make_firmware_metainfo, create_firmware_cab
|
||||
|
||||
|
||||
class Variables:
|
||||
def __init__(self, device_guid, version):
|
||||
self.device_guid = device_guid
|
||||
@ -27,16 +29,18 @@ class Variables:
|
||||
self.release_version = version
|
||||
self.release_description = "Unknown"
|
||||
|
||||
|
||||
def parse_args():
|
||||
"""Parse arguments for this client"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Interact with fwupd daemon")
|
||||
parser.add_argument('exe', nargs='?', help='exe file')
|
||||
parser.add_argument('deviceid', nargs='?',
|
||||
help='DeviceID to operate on(optional)')
|
||||
parser.add_argument('deviceid', nargs='?', help='DeviceID to operate on(optional)')
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def generate_cab(infile, directory, guid, version):
|
||||
output = os.path.join(directory, "firmware.bin")
|
||||
ret = add_header(infile, output, guid)
|
||||
@ -49,10 +53,11 @@ def generate_cab(infile, directory, guid, version):
|
||||
print("Generated CAB file %s" % cab)
|
||||
return cab
|
||||
|
||||
|
||||
def find_uefi_device(client, deviceid):
|
||||
devices = client.get_devices()
|
||||
for item in devices:
|
||||
#match the device we were given
|
||||
# match the device we were given
|
||||
if deviceid:
|
||||
if item.get_id() != deviceid:
|
||||
continue
|
||||
@ -65,10 +70,11 @@ def find_uefi_device(client, deviceid):
|
||||
# return the first hit for UEFI plugin
|
||||
if item.get_plugin() == 'uefi':
|
||||
print("Installing to %s" % item.get_name())
|
||||
return item.get_guid_default(),item.get_id(),item.get_version()
|
||||
return item.get_guid_default(), item.get_id(), item.get_version()
|
||||
print("Couldn't find any UEFI devices")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def prompt_reboot():
|
||||
print("An update requires a reboot to complete")
|
||||
while True:
|
||||
@ -78,18 +84,20 @@ def prompt_reboot():
|
||||
break
|
||||
if res.lower() != 'y':
|
||||
continue
|
||||
#reboot using logind
|
||||
obj = dbus.SystemBus().get_object('org.freedesktop.login1',
|
||||
'/org/freedesktop/login1')
|
||||
# reboot using logind
|
||||
obj = dbus.SystemBus().get_object(
|
||||
'org.freedesktop.login1', '/org/freedesktop/login1'
|
||||
)
|
||||
obj.Reboot(True, dbus_interface='org.freedesktop.login1.Manager')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ARGS = parse_args()
|
||||
CLIENT = Fwupd.Client()
|
||||
CLIENT.connect()
|
||||
check_exists(ARGS.exe)
|
||||
directory = tempfile.mkdtemp()
|
||||
guid, deviceid, version=find_uefi_device(CLIENT, ARGS.deviceid)
|
||||
guid, deviceid, version = find_uefi_device(CLIENT, ARGS.deviceid)
|
||||
cab = generate_cab(ARGS.exe, directory, guid, version)
|
||||
install(CLIENT, cab, deviceid, True, True)
|
||||
prompt_reboot()
|
||||
prompt_reboot()
|
||||
|
@ -5,11 +5,14 @@ import sys
|
||||
import os
|
||||
import gi
|
||||
from gi.repository import GLib
|
||||
gi.require_version('Fwupd', '2.0')
|
||||
from gi.repository import Fwupd #pylint: disable=wrong-import-position
|
||||
|
||||
class Progress():
|
||||
gi.require_version('Fwupd', '2.0')
|
||||
from gi.repository import Fwupd # pylint: disable=wrong-import-position
|
||||
|
||||
|
||||
class Progress:
|
||||
"""Class to track the signal changes of progress events"""
|
||||
|
||||
def __init__(self):
|
||||
self.device = None
|
||||
self.status = None
|
||||
@ -31,55 +34,68 @@ class Progress():
|
||||
self.percent = percent
|
||||
status_str = "["
|
||||
for i in range(0, 50):
|
||||
if i < percent/2:
|
||||
if i < percent / 2:
|
||||
status_str += '*'
|
||||
else:
|
||||
status_str += ' '
|
||||
status_str += "] %d%% %s" %(percent, status)
|
||||
status_str += "] %d%% %s" % (percent, status)
|
||||
self.erase = len(status_str)
|
||||
sys.stdout.write(status_str)
|
||||
sys.stdout.flush()
|
||||
if 'idle' in status:
|
||||
sys.stdout.write("\n")
|
||||
|
||||
|
||||
def parse_args():
|
||||
"""Parse arguments for this client"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Interact with fwupd daemon")
|
||||
parser.add_argument("--allow-older", action="store_true",
|
||||
help="Install older payloads(default False)")
|
||||
parser.add_argument("--allow-reinstall", action="store_true",
|
||||
help="Reinstall payloads(default False)")
|
||||
parser.add_argument("command", choices=["get-devices",
|
||||
"get-details",
|
||||
"install"], help="What to do")
|
||||
parser.add_argument(
|
||||
"--allow-older",
|
||||
action="store_true",
|
||||
help="Install older payloads(default False)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--allow-reinstall",
|
||||
action="store_true",
|
||||
help="Reinstall payloads(default False)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"command", choices=["get-devices", "get-details", "install"], help="What to do"
|
||||
)
|
||||
parser.add_argument('cab', nargs='?', help='CAB file')
|
||||
parser.add_argument('deviceid', nargs='?',
|
||||
help='DeviceID to operate on(optional)')
|
||||
parser.add_argument('deviceid', nargs='?', help='DeviceID to operate on(optional)')
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def get_devices(client):
|
||||
"""Use fwupd client to fetch devices"""
|
||||
devices = client.get_devices()
|
||||
for item in devices:
|
||||
print(item.to_string())
|
||||
|
||||
|
||||
def get_details(client, cab):
|
||||
"""Use fwupd client to fetch details for a CAB file"""
|
||||
devices = client.get_details(cab, None)
|
||||
for device in devices:
|
||||
print(device.to_string())
|
||||
|
||||
def status_changed(client, spec, progress): #pylint: disable=unused-argument
|
||||
"""Signal emitted by fwupd daemon indicating status changed"""
|
||||
progress.status_changed(client.get_percentage(),
|
||||
Fwupd.status_to_string(client.get_status()))
|
||||
|
||||
def device_changed(client, device, progress): #pylint: disable=unused-argument
|
||||
def status_changed(client, spec, progress): # pylint: disable=unused-argument
|
||||
"""Signal emitted by fwupd daemon indicating status changed"""
|
||||
progress.status_changed(
|
||||
client.get_percentage(), Fwupd.status_to_string(client.get_status())
|
||||
)
|
||||
|
||||
|
||||
def device_changed(client, device, progress): # pylint: disable=unused-argument
|
||||
"""Signal emitted by fwupd daemon indicating active device changed"""
|
||||
progress.device_changed(device.get_name())
|
||||
|
||||
|
||||
def install(client, cab, target, older, reinstall):
|
||||
"""Use fwupd client to install CAB file to applicable devices"""
|
||||
# FWUPD_DEVICE_ID_ANY
|
||||
@ -97,12 +113,13 @@ def install(client, cab, target, older, reinstall):
|
||||
parent.connect('notify::status', status_changed, progress)
|
||||
try:
|
||||
client.install(target, cab, flags, None)
|
||||
except GLib.Error as glib_err: #pylint: disable=catching-non-exception
|
||||
except GLib.Error as glib_err: # pylint: disable=catching-non-exception
|
||||
progress.status_changed(0, 'idle')
|
||||
print("%s" % glib_err)
|
||||
sys.exit(1)
|
||||
print("\n")
|
||||
|
||||
|
||||
def check_exists(cab):
|
||||
"""Check that CAB file exists"""
|
||||
if not cab:
|
||||
@ -112,6 +129,7 @@ def check_exists(cab):
|
||||
print("%s doesn't exist or isn't a file" % cab)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ARGS = parse_args()
|
||||
CLIENT = Fwupd.Client()
|
||||
|
@ -5,18 +5,22 @@ import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
def _do_msgattrib(fn):
|
||||
argv = ['msgattrib',
|
||||
'--no-location',
|
||||
'--translated',
|
||||
'--no-wrap',
|
||||
'--sort-output',
|
||||
fn,
|
||||
'--output-file=' + fn]
|
||||
argv = [
|
||||
'msgattrib',
|
||||
'--no-location',
|
||||
'--translated',
|
||||
'--no-wrap',
|
||||
'--sort-output',
|
||||
fn,
|
||||
'--output-file=' + fn,
|
||||
]
|
||||
ret = subprocess.run(argv)
|
||||
if ret.returncode != 0:
|
||||
return
|
||||
|
||||
|
||||
def _do_nukeheader(fn):
|
||||
clean_lines = []
|
||||
with open(fn) as f:
|
||||
@ -32,10 +36,12 @@ def _do_nukeheader(fn):
|
||||
with open(fn, 'w') as f:
|
||||
f.writelines(clean_lines)
|
||||
|
||||
|
||||
def _process_file(fn):
|
||||
_do_msgattrib(fn)
|
||||
_do_nukeheader(fn)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) == 1:
|
||||
print('path required')
|
||||
|
@ -13,6 +13,7 @@ from pkg_resources import parse_version
|
||||
XMLNS = '{http://www.gtk.org/introspection/core/1.0}'
|
||||
XMLNS_C = '{http://www.gtk.org/introspection/c/1.0}'
|
||||
|
||||
|
||||
def usage(return_code):
|
||||
""" print usage and exit with the supplied return code """
|
||||
if return_code == 0:
|
||||
@ -22,6 +23,7 @@ def usage(return_code):
|
||||
out.write("usage: %s <NAME> <INPUT> <OUTPUT>\n" % sys.argv[0])
|
||||
sys.exit(return_code)
|
||||
|
||||
|
||||
class LdVersionScript:
|
||||
""" Rasterize some text """
|
||||
|
||||
@ -58,14 +60,18 @@ class LdVersionScript:
|
||||
for node in cls.findall(XMLNS + 'method'):
|
||||
version_tmp = self._add_node(node)
|
||||
if version_tmp:
|
||||
if not version_lowest or parse_version(version_tmp) < parse_version(version_lowest):
|
||||
if not version_lowest or parse_version(version_tmp) < parse_version(
|
||||
version_lowest
|
||||
):
|
||||
version_lowest = version_tmp
|
||||
|
||||
# add the constructor
|
||||
for node in cls.findall(XMLNS + 'constructor'):
|
||||
version_tmp = self._add_node(node)
|
||||
if version_tmp:
|
||||
if not version_lowest or parse_version(version_tmp) < parse_version(version_lowest):
|
||||
if not version_lowest or parse_version(version_tmp) < parse_version(
|
||||
version_lowest
|
||||
):
|
||||
version_lowest = version_tmp
|
||||
|
||||
# finally add the get_type symbol
|
||||
@ -107,6 +113,7 @@ class LdVersionScript:
|
||||
oldversion = version
|
||||
return verout
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if {'-?', '--help', '--usage'}.intersection(set(sys.argv)):
|
||||
usage(0)
|
||||
|
@ -8,11 +8,13 @@ import struct
|
||||
import glob
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
class Record(object):
|
||||
def __init__(self, filename, cns):
|
||||
self.filename = filename
|
||||
self.cns = cns
|
||||
|
||||
|
||||
def load_pci_ids():
|
||||
pci_vendors = {}
|
||||
pci_vendors[0x1987] = 'Freescale'
|
||||
@ -29,9 +31,11 @@ def load_pci_ids():
|
||||
break
|
||||
return pci_vendors
|
||||
|
||||
|
||||
def _data_to_utf8(s):
|
||||
return s.decode('utf-8', 'replace').replace('\0', ' ')
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
# open files
|
||||
@ -41,47 +45,67 @@ def main():
|
||||
if len(blob) != 4096:
|
||||
print('WARNING: ignoring %s of size %i' % (fn, len(blob)))
|
||||
continue
|
||||
Cns = namedtuple('Cns',
|
||||
'vid ssvid sn mn fr rab ieee cmic mdts cntlid ver ' \
|
||||
'rtd3r rtd3e oaes ctratt rrls rsvd102 oacs acl aerl ' \
|
||||
'frmw lpa elpe npss avscc apsta wctemp cctemp mtfa ' \
|
||||
'hmpre hmmin tnvmcap unvmcap rpmbs edstt dsto fwug ' \
|
||||
'kas hctma mntmt mxtmt sanicap hmminds hmmaxd ' \
|
||||
'nsetidmax rsvd340 anatt anacap anagrpmax nanagrpid ' \
|
||||
'rsvd352 sqes cqes maxcmd nn oncs fuses fna vwc awun ' \
|
||||
'awupf nvscc nwpc acwu rsvd534 sgls mnan rsvd544 ' \
|
||||
'subnqn rsvd1024 ioccsz iorcsz icdoff ctrattr msdbd ' \
|
||||
'rsvd1804 psd vs')
|
||||
Cns = namedtuple(
|
||||
'Cns',
|
||||
'vid ssvid sn mn fr rab ieee cmic mdts cntlid ver '
|
||||
'rtd3r rtd3e oaes ctratt rrls rsvd102 oacs acl aerl '
|
||||
'frmw lpa elpe npss avscc apsta wctemp cctemp mtfa '
|
||||
'hmpre hmmin tnvmcap unvmcap rpmbs edstt dsto fwug '
|
||||
'kas hctma mntmt mxtmt sanicap hmminds hmmaxd '
|
||||
'nsetidmax rsvd340 anatt anacap anagrpmax nanagrpid '
|
||||
'rsvd352 sqes cqes maxcmd nn oncs fuses fna vwc awun '
|
||||
'awupf nvscc nwpc acwu rsvd534 sgls mnan rsvd544 '
|
||||
'subnqn rsvd1024 ioccsz iorcsz icdoff ctrattr msdbd '
|
||||
'rsvd1804 psd vs',
|
||||
)
|
||||
try:
|
||||
cns = Cns._make(struct.unpack('<HH20s40s8sB3pBBHIIIIIH154pHBBBBBBBBHHHII16p' \
|
||||
'16pIHBBHHHHIIHH2pBBII160pBBHIHHBBHHBBH2pII' \
|
||||
'224p256p768pIIHBB244p1024p1024p', blob))
|
||||
cns = Cns._make(
|
||||
struct.unpack(
|
||||
'<HH20s40s8sB3pBBHIIIIIH154pHBBBBBBBBHHHII16p'
|
||||
'16pIHBBHHHHIIHH2pBBII160pBBHIHHBBHHBBH2pII'
|
||||
'224p256p768pIIHBB244p1024p1024p',
|
||||
blob,
|
||||
)
|
||||
)
|
||||
except struct.error as e:
|
||||
print('WARNING: ignoring %s of size %i' % (fn, len(blob)))
|
||||
continue
|
||||
records.append(Record(fn, cns))
|
||||
|
||||
# try to sort in sane way
|
||||
records = sorted(records,
|
||||
key=lambda k: str(k.cns.vid) + k.cns.mn.decode('utf-8', 'replace') + k.cns.sn.decode('utf-8', 'replace'),
|
||||
reverse=True)
|
||||
records = sorted(
|
||||
records,
|
||||
key=lambda k: str(k.cns.vid)
|
||||
+ k.cns.mn.decode('utf-8', 'replace')
|
||||
+ k.cns.sn.decode('utf-8', 'replace'),
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
# export csv
|
||||
with open('all.csv', 'w', newline='') as csvfile:
|
||||
exp = csv.writer(csvfile)
|
||||
exp.writerow(['id', 'vid', 'sn', 'mn', 'fr',
|
||||
'rrls', 'frmw', 'fwug', 'subnqn', 'vs'])
|
||||
exp.writerow(
|
||||
['id', 'vid', 'sn', 'mn', 'fr', 'rrls', 'frmw', 'fwug', 'subnqn', 'vs']
|
||||
)
|
||||
for r in records:
|
||||
cns = r.cns
|
||||
sn = cns.sn.decode('utf-8', 'replace').replace('\0', ' ')
|
||||
mn = cns.mn.decode('utf-8', 'replace').replace('\0', ' ')
|
||||
fr = cns.fr.decode('utf-8', 'replace').replace('\0', ' ')
|
||||
exp.writerow([os.path.basename(r.filename)[:6],
|
||||
'%04x' % cns.vid,
|
||||
sn, mn, fr, cns.rrls,
|
||||
'%02x' % cns.frmw,
|
||||
cns.fwug, cns.subnqn,
|
||||
binascii.hexlify(cns.vs)])
|
||||
exp.writerow(
|
||||
[
|
||||
os.path.basename(r.filename)[:6],
|
||||
'%04x' % cns.vid,
|
||||
sn,
|
||||
mn,
|
||||
fr,
|
||||
cns.rrls,
|
||||
'%02x' % cns.frmw,
|
||||
cns.fwug,
|
||||
cns.subnqn,
|
||||
binascii.hexlify(cns.vs),
|
||||
]
|
||||
)
|
||||
|
||||
# frmw stats
|
||||
s1ro_cnt = 0
|
||||
@ -92,7 +116,7 @@ def main():
|
||||
s1ro_cnt += 1
|
||||
if (r.cns.frmw & 0x10) >> 4:
|
||||
fawr_cnt += 1
|
||||
nfws = (r.cns.frmw & 0x0e) >> 1
|
||||
nfws = (r.cns.frmw & 0x0E) >> 1
|
||||
if nfws in nfws_map:
|
||||
nfws_map[nfws] += 1
|
||||
continue
|
||||
@ -125,4 +149,5 @@ def main():
|
||||
vs_records.append(r)
|
||||
print('nr_vs=%i' % len(vs_records))
|
||||
|
||||
|
||||
main()
|
||||
|
@ -12,24 +12,43 @@ import sys
|
||||
import shutil
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
TAG = b'#\x00'
|
||||
|
||||
|
||||
def parse_args():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Self extracting firmware updater")
|
||||
parser.add_argument("--directory", help="Directory to extract to")
|
||||
parser.add_argument("--cleanup", action='store_true', help="Remove tools when done with installation")
|
||||
parser.add_argument("--verbose", action='store_true', help="Run the tool in verbose mode")
|
||||
parser.add_argument("--allow-reinstall", action='store_true', help="Allow re-installing existing firmware versions")
|
||||
parser.add_argument("--allow-older", action='store_true', help="Allow downgrading firmware versions")
|
||||
parser.add_argument("command", choices=["install", "extract"], help="Command to run")
|
||||
parser.add_argument(
|
||||
"--cleanup",
|
||||
action='store_true',
|
||||
help="Remove tools when done with installation",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--verbose", action='store_true', help="Run the tool in verbose mode"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--allow-reinstall",
|
||||
action='store_true',
|
||||
help="Allow re-installing existing firmware versions",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--allow-older", action='store_true', help="Allow downgrading firmware versions"
|
||||
)
|
||||
parser.add_argument(
|
||||
"command", choices=["install", "extract"], help="Command to run"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
def error (msg):
|
||||
|
||||
def error(msg):
|
||||
print(msg)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def bytes_slicer(length, source):
|
||||
start = 0
|
||||
stop = length
|
||||
@ -38,68 +57,71 @@ def bytes_slicer(length, source):
|
||||
start = stop
|
||||
stop += length
|
||||
|
||||
|
||||
def get_zip():
|
||||
script = os.path.realpath (__file__)
|
||||
script = os.path.realpath(__file__)
|
||||
bytes_out = io.BytesIO()
|
||||
with open(script, 'rb') as source:
|
||||
for line in source:
|
||||
if not line.startswith(TAG):
|
||||
continue
|
||||
bytes_out.write(b64decode(line[len(TAG):-1]))
|
||||
bytes_out.write(b64decode(line[len(TAG) : -1]))
|
||||
return bytes_out
|
||||
|
||||
def unzip (destination):
|
||||
zipf = get_zip ()
|
||||
source = zipfile.ZipFile (zipf, 'r')
|
||||
|
||||
def unzip(destination):
|
||||
zipf = get_zip()
|
||||
source = zipfile.ZipFile(zipf, 'r')
|
||||
for item in source.namelist():
|
||||
# extract handles the sanitization
|
||||
source.extract (item, destination)
|
||||
source.extract(item, destination)
|
||||
|
||||
def copy_cabs (source, target):
|
||||
if not os.path.exists (target):
|
||||
os.makedirs (target)
|
||||
|
||||
def copy_cabs(source, target):
|
||||
if not os.path.exists(target):
|
||||
os.makedirs(target)
|
||||
cabs = []
|
||||
for root, dirs, files in os.walk (source):
|
||||
for root, dirs, files in os.walk(source):
|
||||
for f in files:
|
||||
if (f.endswith ('.cab')):
|
||||
if f.endswith('.cab'):
|
||||
origf = os.path.join(root, f)
|
||||
shutil.copy (origf, target)
|
||||
cabs.append (os.path.join (target, f))
|
||||
shutil.copy(origf, target)
|
||||
cabs.append(os.path.join(target, f))
|
||||
return cabs
|
||||
|
||||
|
||||
def install_snap (directory, verbose, allow_reinstall, allow_older, uninstall):
|
||||
def install_snap(directory, verbose, allow_reinstall, allow_older, uninstall):
|
||||
app = 'fwupd'
|
||||
common = '/root/snap/%s/common' % app
|
||||
|
||||
#check if snap is installed
|
||||
# check if snap is installed
|
||||
with open(os.devnull, 'w') as devnull:
|
||||
subprocess.run (['snap'], check=True, stdout=devnull, stderr=devnull)
|
||||
subprocess.run(['snap'], check=True, stdout=devnull, stderr=devnull)
|
||||
|
||||
#check existing installed
|
||||
# check existing installed
|
||||
cmd = ['snap', 'list', app]
|
||||
with open(os.devnull, 'w') as devnull:
|
||||
if verbose:
|
||||
print(cmd)
|
||||
ret = subprocess.run (cmd, stdout=devnull, stderr=devnull)
|
||||
ret = subprocess.run(cmd, stdout=devnull, stderr=devnull)
|
||||
if ret.returncode == 0:
|
||||
cmd = ['snap', 'remove', app]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
subprocess.run (cmd, check=True)
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
# install the snap
|
||||
cmd = ['snap', 'ack', os.path.join (directory, 'fwupd.assert')]
|
||||
cmd = ['snap', 'ack', os.path.join(directory, 'fwupd.assert')]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
subprocess.run (cmd, check=True)
|
||||
cmd = ['snap', 'install', '--classic', os.path.join (directory, 'fwupd.snap')]
|
||||
subprocess.run(cmd, check=True)
|
||||
cmd = ['snap', 'install', '--classic', os.path.join(directory, 'fwupd.snap')]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
subprocess.run (cmd, check=True)
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
# copy the CAB files
|
||||
cabs = copy_cabs (directory, common)
|
||||
cabs = copy_cabs(directory, common)
|
||||
|
||||
# run the snap
|
||||
for cab in cabs:
|
||||
@ -111,76 +133,77 @@ def install_snap (directory, verbose, allow_reinstall, allow_older, uninstall):
|
||||
if verbose:
|
||||
cmd += ["--verbose"]
|
||||
print(cmd)
|
||||
subprocess.run (cmd)
|
||||
subprocess.run(cmd)
|
||||
|
||||
#remove copied cabs
|
||||
# remove copied cabs
|
||||
for f in cabs:
|
||||
os.remove(f)
|
||||
|
||||
#cleanup
|
||||
# cleanup
|
||||
if uninstall:
|
||||
cmd = ['snap', 'remove', app]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
subprocess.run (cmd)
|
||||
subprocess.run(cmd)
|
||||
|
||||
def install_flatpak (directory, verbose, allow_reinstall, allow_older, uninstall):
|
||||
|
||||
def install_flatpak(directory, verbose, allow_reinstall, allow_older, uninstall):
|
||||
app = 'org.freedesktop.fwupd'
|
||||
common = '%s/.var/app/%s' % (os.getenv ('HOME'), app)
|
||||
common = '%s/.var/app/%s' % (os.getenv('HOME'), app)
|
||||
|
||||
with open(os.devnull, 'w') as devnull:
|
||||
if not verbose:
|
||||
output = devnull
|
||||
else:
|
||||
output = None
|
||||
#look for dependencies
|
||||
# look for dependencies
|
||||
dep = 'org.gnome.Platform/x86_64/3.30'
|
||||
repo = 'flathub'
|
||||
repo_url = 'https://flathub.org/repo/flathub.flatpakrepo'
|
||||
cmd = ['flatpak', 'info', dep]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
ret = subprocess.run (cmd, stdout=output, stderr=output)
|
||||
#not installed
|
||||
ret = subprocess.run(cmd, stdout=output, stderr=output)
|
||||
# not installed
|
||||
if ret.returncode != 0:
|
||||
#look for remotes
|
||||
# look for remotes
|
||||
cmd = ['flatpak', 'remote-info', repo, dep]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
ret = subprocess.run (cmd, stdout=output, stderr=output)
|
||||
#not enabled, enable it
|
||||
ret = subprocess.run(cmd, stdout=output, stderr=output)
|
||||
# not enabled, enable it
|
||||
if ret.returncode != 0:
|
||||
cmd = ['flatpak', 'remote-add', repo, repo_url]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
ret = subprocess.run (cmd, stderr=output)
|
||||
ret = subprocess.run(cmd, stderr=output)
|
||||
# install dep
|
||||
cmd = ['flatpak', 'install', repo, dep]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
ret = subprocess.run (cmd)
|
||||
ret = subprocess.run(cmd)
|
||||
|
||||
#check existing installed
|
||||
# check existing installed
|
||||
cmd = ['flatpak', 'info', app]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
ret = subprocess.run (cmd, stdout=output, stderr=output)
|
||||
ret = subprocess.run(cmd, stdout=output, stderr=output)
|
||||
if ret.returncode == 0:
|
||||
cmd = ['flatpak', 'remove', app]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
subprocess.run (cmd, check=True)
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
#install the flatpak
|
||||
cmd = ['flatpak', 'install', os.path.join (directory, 'fwupd.flatpak')]
|
||||
# install the flatpak
|
||||
cmd = ['flatpak', 'install', os.path.join(directory, 'fwupd.flatpak')]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
subprocess.run (cmd, check=True)
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
# copy the CAB files
|
||||
cabs = copy_cabs (directory, common)
|
||||
cabs = copy_cabs(directory, common)
|
||||
|
||||
#run command
|
||||
# run command
|
||||
for cab in cabs:
|
||||
cmd = ['flatpak', 'run', app, 'install', cab]
|
||||
if allow_reinstall:
|
||||
@ -190,18 +213,19 @@ def install_flatpak (directory, verbose, allow_reinstall, allow_older, uninstall
|
||||
if verbose:
|
||||
cmd += ["--verbose"]
|
||||
print(cmd)
|
||||
subprocess.run (cmd)
|
||||
subprocess.run(cmd)
|
||||
|
||||
#remove copied cabs
|
||||
# remove copied cabs
|
||||
for f in cabs:
|
||||
os.remove(f)
|
||||
|
||||
#cleanup
|
||||
# cleanup
|
||||
if uninstall:
|
||||
cmd = ['flatpak', 'remove', app]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
subprocess.run (cmd)
|
||||
subprocess.run(cmd)
|
||||
|
||||
|
||||
# Check which package to use
|
||||
# - return False to use packaged version
|
||||
@ -218,15 +242,21 @@ def use_included_version(minimum_version):
|
||||
return True
|
||||
if minimum_version:
|
||||
if minimum_version > version:
|
||||
print("fwupd %s is already installed but this package requires %s" %
|
||||
(version.version, minimum_version))
|
||||
print(
|
||||
"fwupd %s is already installed but this package requires %s"
|
||||
% (version.version, minimum_version)
|
||||
)
|
||||
else:
|
||||
print("Using existing fwupd version %s already installed on system." % version.version)
|
||||
print(
|
||||
"Using existing fwupd version %s already installed on system."
|
||||
% version.version
|
||||
)
|
||||
return False
|
||||
else:
|
||||
print("fwupd %s is installed and must be removed" % version.version)
|
||||
return remove_packaged_version(pkg, cache)
|
||||
|
||||
|
||||
def remove_packaged_version(pkg, cache):
|
||||
res = False
|
||||
while True:
|
||||
@ -244,13 +274,14 @@ def remove_packaged_version(pkg, cache):
|
||||
raise Exception("Need to remove packaged version")
|
||||
return True
|
||||
|
||||
|
||||
def install_builtin(directory, verbose, allow_reinstall, allow_older):
|
||||
cabs = []
|
||||
for root, dirs, files in os.walk (directory):
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for f in files:
|
||||
if f.endswith('.cab'):
|
||||
cabs.append(os.path.join(root, f))
|
||||
#run command
|
||||
# run command
|
||||
for cab in cabs:
|
||||
cmd = ['fwupdmgr', 'install', cab]
|
||||
if allow_reinstall:
|
||||
@ -262,11 +293,12 @@ def install_builtin(directory, verbose, allow_reinstall, allow_older):
|
||||
print(cmd)
|
||||
subprocess.run(cmd)
|
||||
|
||||
def run_installation (directory, verbose, allow_reinstall, allow_older, uninstall):
|
||||
|
||||
def run_installation(directory, verbose, allow_reinstall, allow_older, uninstall):
|
||||
try_snap = False
|
||||
try_flatpak = False
|
||||
|
||||
#determine if a minimum version was specified
|
||||
# determine if a minimum version was specified
|
||||
minimum_path = os.path.join(directory, "minimum")
|
||||
minimum = None
|
||||
if os.path.exists(minimum_path):
|
||||
@ -278,44 +310,60 @@ def run_installation (directory, verbose, allow_reinstall, allow_older, uninstal
|
||||
return
|
||||
|
||||
# determine what self extracting binary has
|
||||
if os.path.exists (os.path.join (directory, 'fwupd.snap')) and \
|
||||
os.path.exists (os.path.join (directory, 'fwupd.assert')):
|
||||
if os.path.exists(os.path.join(directory, 'fwupd.snap')) and os.path.exists(
|
||||
os.path.join(directory, 'fwupd.assert')
|
||||
):
|
||||
try_snap = True
|
||||
if os.path.exists (os.path.join (directory, 'fwupd.flatpak')):
|
||||
if os.path.exists(os.path.join(directory, 'fwupd.flatpak')):
|
||||
try_flatpak = True
|
||||
|
||||
if try_snap:
|
||||
try:
|
||||
install_snap (directory, verbose, allow_reinstall, allow_older, uninstall)
|
||||
install_snap(directory, verbose, allow_reinstall, allow_older, uninstall)
|
||||
return True
|
||||
except Exception as _:
|
||||
if verbose:
|
||||
print ("Snap installation failed")
|
||||
print("Snap installation failed")
|
||||
if not try_flatpak:
|
||||
error ("Snap installation failed")
|
||||
error("Snap installation failed")
|
||||
if try_flatpak:
|
||||
install_flatpak (directory, verbose, allow_reinstall, allow_older, uninstall)
|
||||
install_flatpak(directory, verbose, allow_reinstall, allow_older, uninstall)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_args()
|
||||
if 'extract' in args.command:
|
||||
if args.allow_reinstall:
|
||||
error ("allow-reinstall argument doesn't make sense with command %s" % args.command)
|
||||
error(
|
||||
"allow-reinstall argument doesn't make sense with command %s"
|
||||
% args.command
|
||||
)
|
||||
if args.allow_older:
|
||||
error ("allow-older argument doesn't make sense with command %s" % args.command)
|
||||
error(
|
||||
"allow-older argument doesn't make sense with command %s" % args.command
|
||||
)
|
||||
if args.cleanup:
|
||||
error ("Cleanup argument doesn't make sense with command %s" % args.command)
|
||||
error("Cleanup argument doesn't make sense with command %s" % args.command)
|
||||
if args.directory is None:
|
||||
error ("No directory specified")
|
||||
if not os.path.exists (args.directory):
|
||||
print ("Creating %s" % args.directory)
|
||||
os.makedirs (args.directory)
|
||||
unzip (args.directory)
|
||||
error("No directory specified")
|
||||
if not os.path.exists(args.directory):
|
||||
print("Creating %s" % args.directory)
|
||||
os.makedirs(args.directory)
|
||||
unzip(args.directory)
|
||||
else:
|
||||
if args.directory:
|
||||
error ("Directory argument %s doesn't make sense with command %s" % (args.directory, args.command))
|
||||
error(
|
||||
"Directory argument %s doesn't make sense with command %s"
|
||||
% (args.directory, args.command)
|
||||
)
|
||||
if os.getuid() != 0:
|
||||
error ("This tool must be run as root")
|
||||
with tempfile.TemporaryDirectory (prefix='fwupd') as target:
|
||||
unzip (target)
|
||||
run_installation (target, args.verbose, args.allow_reinstall, args.allow_older, args.cleanup)
|
||||
error("This tool must be run as root")
|
||||
with tempfile.TemporaryDirectory(prefix='fwupd') as target:
|
||||
unzip(target)
|
||||
run_installation(
|
||||
target,
|
||||
args.verbose,
|
||||
args.allow_reinstall,
|
||||
args.allow_older,
|
||||
args.cleanup,
|
||||
)
|
||||
|
@ -14,22 +14,43 @@ import tempfile
|
||||
import zipfile
|
||||
from assets.header import TAG
|
||||
|
||||
def error (msg):
|
||||
|
||||
def error(msg):
|
||||
print(msg)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def parse_args():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description="Generate a standalone firmware updater")
|
||||
parser.add_argument("--disable-snap-download", action='store_true', help="Don't download support for snap")
|
||||
parser.add_argument("--disable-flatpak-download", action='store_true', help="Don't download support for flatpak")
|
||||
parser.add_argument("--snap-channel", help="Channel to download snap from (optional)")
|
||||
parser.add_argument("--minimum", help="Use already installed fwupd version if at least this version")
|
||||
parser.add_argument("cab", help="CAB file or directory containing CAB files to automatically install")
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate a standalone firmware updater"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--disable-snap-download",
|
||||
action='store_true',
|
||||
help="Don't download support for snap",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--disable-flatpak-download",
|
||||
action='store_true',
|
||||
help="Don't download support for flatpak",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--snap-channel", help="Channel to download snap from (optional)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--minimum", help="Use already installed fwupd version if at least this version"
|
||||
)
|
||||
parser.add_argument(
|
||||
"cab",
|
||||
help="CAB file or directory containing CAB files to automatically install",
|
||||
)
|
||||
parser.add_argument('target', help='target file to create')
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def bytes_slicer(length, source):
|
||||
start = 0
|
||||
stop = length
|
||||
@ -38,73 +59,87 @@ def bytes_slicer(length, source):
|
||||
start = stop
|
||||
stop += length
|
||||
|
||||
def generate_installer (directory, target):
|
||||
asset_base = os.path.join (os.path.dirname(os.path.realpath(__file__)),
|
||||
"assets")
|
||||
|
||||
#header
|
||||
shutil.copy (os.path.join (asset_base, "header.py"), target)
|
||||
def generate_installer(directory, target):
|
||||
asset_base = os.path.join(os.path.dirname(os.path.realpath(__file__)), "assets")
|
||||
|
||||
#zip file
|
||||
# header
|
||||
shutil.copy(os.path.join(asset_base, "header.py"), target)
|
||||
|
||||
# zip file
|
||||
buffer = io.BytesIO()
|
||||
archive = zipfile.ZipFile(buffer, "a")
|
||||
for root, dirs, files in os.walk (directory):
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for f in files:
|
||||
source = os.path.join(root, f)
|
||||
archive_fname = source.split (directory) [1]
|
||||
archive_fname = source.split(directory)[1]
|
||||
archive.write(source, archive_fname)
|
||||
if 'DEBUG' in os.environ:
|
||||
print (archive.namelist())
|
||||
print(archive.namelist())
|
||||
archive.close()
|
||||
|
||||
with open (target, 'ab') as bytes_out:
|
||||
with open(target, 'ab') as bytes_out:
|
||||
encoded = b64encode(buffer.getvalue())
|
||||
for section in bytes_slicer(64, encoded):
|
||||
bytes_out.write(TAG)
|
||||
bytes_out.write(section)
|
||||
bytes_out.write(b'\n')
|
||||
|
||||
def download_snap (directory, channel):
|
||||
|
||||
def download_snap(directory, channel):
|
||||
cmd = ['snap', 'download', 'fwupd']
|
||||
if channel is not None:
|
||||
cmd += ['--channel', channel]
|
||||
if 'DEBUG' in os.environ:
|
||||
print(cmd)
|
||||
subprocess.run (cmd, cwd=directory, check=True)
|
||||
for f in os.listdir (directory):
|
||||
subprocess.run(cmd, cwd=directory, check=True)
|
||||
for f in os.listdir(directory):
|
||||
# the signatures associated with the snap
|
||||
if f.endswith(".assert"):
|
||||
shutil.move (os.path.join(directory, f), os.path.join(directory, 'fwupd.assert'))
|
||||
shutil.move(
|
||||
os.path.join(directory, f), os.path.join(directory, 'fwupd.assert')
|
||||
)
|
||||
# the snap binary itself
|
||||
elif f.endswith(".snap"):
|
||||
shutil.move (os.path.join(directory, f), os.path.join(directory, 'fwupd.snap'))
|
||||
shutil.move(
|
||||
os.path.join(directory, f), os.path.join(directory, 'fwupd.snap')
|
||||
)
|
||||
|
||||
def download_cab_file (directory, uri):
|
||||
|
||||
def download_cab_file(directory, uri):
|
||||
cmd = ['wget', uri]
|
||||
if 'DEBUG' in os.environ:
|
||||
print(cmd)
|
||||
subprocess.run (cmd, cwd=directory, check=True)
|
||||
subprocess.run(cmd, cwd=directory, check=True)
|
||||
|
||||
def download_flatpak (directory):
|
||||
|
||||
def download_flatpak(directory):
|
||||
dep = 'org.freedesktop.fwupd'
|
||||
flatpak_dir = os.path.join(os.getenv('HOME'),'.local', 'share', 'flatpak')
|
||||
flatpak_dir = os.path.join(os.getenv('HOME'), '.local', 'share', 'flatpak')
|
||||
verbose = 'DEBUG' in os.environ
|
||||
|
||||
#check if we have installed locally already or not
|
||||
if not os.path.exists (os.path.join (flatpak_dir, 'app', dep)):
|
||||
# check if we have installed locally already or not
|
||||
if not os.path.exists(os.path.join(flatpak_dir, 'app', dep)):
|
||||
# install into local user's repo
|
||||
cmd = ['flatpak', 'install', '--user',
|
||||
'https://www.flathub.org/repo/appstream/org.freedesktop.fwupd.flatpakref', '--no-deps', '-y']
|
||||
cmd = [
|
||||
'flatpak',
|
||||
'install',
|
||||
'--user',
|
||||
'https://www.flathub.org/repo/appstream/org.freedesktop.fwupd.flatpakref',
|
||||
'--no-deps',
|
||||
'-y',
|
||||
]
|
||||
if verbose:
|
||||
print(cmd)
|
||||
subprocess.run (cmd, cwd=directory, check=True)
|
||||
subprocess.run(cmd, cwd=directory, check=True)
|
||||
|
||||
# generate a bundle
|
||||
repo = os.path.join(flatpak_dir, 'repo')
|
||||
cmd = ['flatpak', 'build-bundle', repo, 'fwupd.flatpak', dep, 'stable']
|
||||
if verbose:
|
||||
print(cmd)
|
||||
subprocess.run (cmd, cwd=directory, check=True)
|
||||
subprocess.run(cmd, cwd=directory, check=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_args()
|
||||
@ -112,27 +147,27 @@ if __name__ == '__main__':
|
||||
if not args.cab.startswith("http"):
|
||||
local = args.cab
|
||||
|
||||
with tempfile.TemporaryDirectory (prefix='fwupd') as directory:
|
||||
with tempfile.TemporaryDirectory(prefix='fwupd') as directory:
|
||||
if local:
|
||||
if not os.path.exists (local):
|
||||
error ("%s doesn't exist" % local)
|
||||
if not os.path.exists(local):
|
||||
error("%s doesn't exist" % local)
|
||||
if not os.path.isdir(local):
|
||||
shutil.copy (local, directory)
|
||||
shutil.copy(local, directory)
|
||||
else:
|
||||
for root, dirs, files in os.walk(local):
|
||||
for f in files:
|
||||
shutil.copy (os.path.join(root, f), directory)
|
||||
shutil.copy(os.path.join(root, f), directory)
|
||||
else:
|
||||
download_cab_file (directory, args.cab)
|
||||
download_cab_file(directory, args.cab)
|
||||
|
||||
if not args.disable_snap_download:
|
||||
download_snap (directory, args.snap_channel)
|
||||
download_snap(directory, args.snap_channel)
|
||||
|
||||
if not args.disable_flatpak_download:
|
||||
download_flatpak (directory)
|
||||
download_flatpak(directory)
|
||||
|
||||
if args.minimum:
|
||||
with open(os.path.join(directory, "minimum"), "w") as wfd:
|
||||
wfd.write(args.minimum)
|
||||
|
||||
generate_installer (directory, args.target)
|
||||
generate_installer(directory, args.target)
|
||||
|
@ -10,6 +10,7 @@ SPDX-License-Identifier: LGPL-2.1+
|
||||
import sys
|
||||
import hashlib
|
||||
|
||||
|
||||
def usage(return_code):
|
||||
""" print usage and exit with the supplied return code """
|
||||
if return_code == 0:
|
||||
@ -19,6 +20,7 @@ def usage(return_code):
|
||||
out.write("usage: fu-hash.py <HEADER> <SRC1> <SRC2>...")
|
||||
sys.exit(return_code)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if {'-?', '--help', '--usage'}.intersection(set(sys.argv)):
|
||||
usage(0)
|
||||
|
@ -19,6 +19,7 @@ def _find_part_by_id(parts, part_id):
|
||||
return part
|
||||
return None
|
||||
|
||||
|
||||
# finds a memory layout for a part, climbing up the tree to the parent if reqd.
|
||||
def _find_mem_layout(parts, part):
|
||||
if 'memory-application' in part:
|
||||
@ -26,7 +27,7 @@ def _find_mem_layout(parts, part):
|
||||
if memory_flash:
|
||||
return memory_flash
|
||||
|
||||
#look at the parent
|
||||
# look at the parent
|
||||
if 'parent' in part:
|
||||
parent = _find_part_by_id(parts, part['parent'])
|
||||
if parent:
|
||||
@ -34,6 +35,7 @@ def _find_mem_layout(parts, part):
|
||||
print('no parent ', part['parent'], 'found for', part['id'])
|
||||
return None
|
||||
|
||||
|
||||
# parses the weird syntax of avrdude.conf and makes lots of nested dictionaries
|
||||
def _parse_parts(fn_source):
|
||||
print("reading", fn_source)
|
||||
@ -100,9 +102,11 @@ def _parse_parts(fn_source):
|
||||
continue
|
||||
return parts
|
||||
|
||||
|
||||
def _get_longest_substring(s1, s2):
|
||||
match = SequenceMatcher(None, s1, s2).find_longest_match(0, len(s1), 0, len(s2))
|
||||
return s2[match.b: match.b + match.size]
|
||||
return s2[match.b : match.b + match.size]
|
||||
|
||||
|
||||
# writes important data to the quirks file
|
||||
def _write_quirks(parts, fn_destination):
|
||||
@ -148,13 +152,16 @@ def _write_quirks(parts, fn_destination):
|
||||
|
||||
for chip_id in results:
|
||||
result = results[chip_id]
|
||||
outp.append('# ' + result['desc'] + ' [USER] USER=0x%x' % result['size'] + '\n')
|
||||
outp.append(
|
||||
'# ' + result['desc'] + ' [USER] USER=0x%x' % result['size'] + '\n'
|
||||
)
|
||||
outp.append(chip_id + '=' + result['mem_layout'] + '\n\n')
|
||||
|
||||
# write file
|
||||
print("writing", fn_destination)
|
||||
open(fn_destination, 'w').writelines(outp)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 3:
|
||||
print("USAGE: %s avrdude.conf tmp.quirk" % sys.argv[0])
|
||||
|
Loading…
Reference in New Issue
Block a user