pmb.sideload: Query architecture from foreign device (MR 2282)

Instead of assuming the architecture of the foreign device to be what
the user selected in pmbootstrap init, actually query the architecture
from the device and use that.

This does mean that one extra ssh connection is necessary, which does
slow down the procedure somewhat. However, I think that is worth the
user experience improvement this brings.

Also, the deduction process can be skipped by manually specifying
--arch in the sideload invocation should it fail, or if one really wants
to skip that extra ssh roundtrip.

Related: https://gitlab.com/postmarketOS/pmbootstrap/-/issues/2317
This commit is contained in:
Newbyte 2024-03-23 14:51:35 +01:00
parent 1fc83f8bce
commit c2a069b1f5
No known key found for this signature in database
GPG key ID: 8A700086A9FE41FD
3 changed files with 18 additions and 5 deletions

View file

@ -141,8 +141,6 @@ def checksum(args):
def sideload(args): def sideload(args):
arch = args.deviceinfo["arch"]
if args.arch:
arch = args.arch arch = args.arch
user = args.user user = args.user
host = args.host host = args.host

View file

@ -220,8 +220,8 @@ def arguments_sideload(subparser):
default="22") default="22")
ret.add_argument("--user", help="use a different username than the" ret.add_argument("--user", help="use a different username than the"
" one set in init") " one set in init")
ret.add_argument("--arch", help="use a different architecture than the one" ret.add_argument("--arch", help="skip automatic architecture deduction and use the"
" set in init") " given value")
ret.add_argument("--install-key", help="install the apk key from this" ret.add_argument("--install-key", help="install the apk key from this"
" machine if needed", " machine if needed",
action="store_true", dest="install_key") action="store_true", dest="install_key")

View file

@ -3,10 +3,12 @@
import glob import glob
import os import os
import logging import logging
from argparse import Namespace
import pmb.helpers.run import pmb.helpers.run
import pmb.helpers.run_core import pmb.helpers.run_core
import pmb.parse.apkindex import pmb.parse.apkindex
import pmb.parse.arch
import pmb.config.pmaports import pmb.config.pmaports
import pmb.build import pmb.build
@ -35,6 +37,16 @@ def scp_abuild_key(args, user, host, port):
pmb.helpers.run.user(args, command, output="tui") pmb.helpers.run.user(args, command, output="tui")
def ssh_find_arch(args: Namespace, user: str, host: str, port: str) -> str:
"""Connect to a device via ssh and query the architecture."""
logging.info(f"Querying architecture of {user}@{host}")
command = ["ssh", "-p", port, f"{user}@{host}", "uname -m"]
output = pmb.helpers.run.user(args, command, output_return=True)
foreign_machine_type = output.strip() # Remove newline from output
alpine_architecture = pmb.parse.arch.machine_type_to_alpine(foreign_machine_type)
return alpine_architecture
def ssh_install_apks(args, user, host, port, paths): def ssh_install_apks(args, user, host, port, paths):
""" Copy binary packages via SCP and install them via SSH. """ Copy binary packages via SCP and install them via SSH.
:param user: target device ssh username :param user: target device ssh username
@ -74,6 +86,9 @@ def sideload(args, user, host, port, arch, copy_key, pkgnames):
paths = [] paths = []
channel = pmb.config.pmaports.read_config(args)["channel"] channel = pmb.config.pmaports.read_config(args)["channel"]
if arch is None:
arch = ssh_find_arch(args, user, host, port)
for pkgname in pkgnames: for pkgname in pkgnames:
data_repo = pmb.parse.apkindex.package(args, pkgname, arch, True) data_repo = pmb.parse.apkindex.package(args, pkgname, arch, True)
apk_file = f"{pkgname}-{data_repo['version']}.apk" apk_file = f"{pkgname}-{data_repo['version']}.apk"