fwupd/contrib/standalone-installer/make.py
2021-04-08 10:43:29 -05:00

174 lines
4.9 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(
"--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
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):
dep = "org.freedesktop.fwupd"
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)):
# install into local user's repo
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)
# 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)
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)
if args.minimum:
with open(os.path.join(directory, "minimum"), "w") as wfd:
wfd.write(args.minimum)
generate_installer(directory, args.target)