mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-28 07:57:08 +00:00

This is meant to produce standalone installer binaries that can operate on machines without current tools or internet access. It works by wrapping around the container technologies snap and flatpak and putting all the pieces together.
119 lines
3.8 KiB
Python
Executable File
119 lines
3.8 KiB
Python
Executable File
#!/usr/bin/python3
|
|
#
|
|
# Copyright (C) 2017 Dell, Inc.
|
|
#
|
|
# SPDX-License-Identifier: LGPL-2.1+
|
|
#
|
|
from base64 import b64encode
|
|
import io
|
|
import os
|
|
import subprocess
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
import zipfile
|
|
from assets.header import TAG
|
|
|
|
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("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
|
|
while start < len(source):
|
|
yield source[start:stop]
|
|
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)
|
|
|
|
#zip file
|
|
buffer = io.BytesIO()
|
|
archive = zipfile.ZipFile(buffer, "a")
|
|
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.write(source, archive_fname)
|
|
if 'DEBUG' in os.environ:
|
|
print (archive.namelist())
|
|
archive.close()
|
|
|
|
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):
|
|
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):
|
|
# the signatures associated with the snap
|
|
if f.endswith(".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'))
|
|
|
|
def download_cab_file (directory, uri):
|
|
cmd = ['wget', uri]
|
|
if 'DEBUG' in os.environ:
|
|
print(cmd)
|
|
subprocess.run (cmd, cwd=directory, check=True)
|
|
|
|
def download_flatpak (directory):
|
|
cmd = ['wget', 'https://people.freedesktop.org/~hughsient/temp/fwupd.flatpak', '-O', 'fwupd.flatpak']
|
|
if 'DEBUG' in os.environ:
|
|
print(cmd)
|
|
subprocess.run (cmd, cwd=directory, check=True)
|
|
|
|
if __name__ == '__main__':
|
|
args = parse_args()
|
|
|
|
if not args.cab.startswith("http"):
|
|
local = args.cab
|
|
|
|
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.isdir(local):
|
|
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)
|
|
else:
|
|
download_cab_file (directory, args.cab)
|
|
|
|
if not args.disable_snap_download:
|
|
download_snap (directory, args.snap_channel)
|
|
|
|
if not args.disable_flatpak_download:
|
|
download_flatpak (directory)
|
|
|
|
generate_installer (directory, args.target)
|