[Concept,16/20] buildman: Install toolchains on remote machines

Message ID 20260316154733.1587261-17-sjg@u-boot.org
State New
Headers
Series buildman: Add distributed builds |

Commit Message

Simon Glass March 16, 2026, 3:47 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

Add the ability to fetch missing toolchains on remote machines when
probing with the --machines option.

When --machines-fetch-arch is passed alongside --machines, any toolchain
architectures available locally but missing on a remote machine are
fetched via 'buildman --fetch-arch' over SSH.

Pass the local toolchain set as needed_archs to check_toolchains() so
that missing toolchains can be identified by comparison with the local
host.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/buildman/cmdline.py      |  4 ++++
 tools/buildman/control.py      |  5 +++--
 tools/buildman/test_machine.py | 14 ++++++++++++++
 3 files changed, 21 insertions(+), 2 deletions(-)
  

Patch

diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py
index b284b2cbbfa..a85da069d24 100644
--- a/tools/buildman/cmdline.py
+++ b/tools/buildman/cmdline.py
@@ -109,6 +109,10 @@  def add_upto_m(parser):
           default=False, dest='machines',
           help='Probe all remote machines from [machines] config and show '
                'their status and available toolchains')
+    parser.add_argument('--machines-fetch-arch', action='store_true',
+          default=False,
+          help='Fetch missing toolchains on remote machines (implies '
+               '--machines)')
     parser.add_argument('--machines-buildman-path', type=str,
           default='buildman',
           help='Path to buildman on remote machines (default: %(default)s)')
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index 97f6ffcbfd2..7515932a2e4 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -760,9 +760,10 @@  def do_buildman(args, toolchains=None, make_func=None, brds=None,
     col = terminal.Color()
 
     # Handle --machines: probe remote machines and show status
-    if args.machines:
+    if args.machines or args.machines_fetch_arch:
         return machine.do_probe_machines(
-            col, buildman_path=args.machines_buildman_path)
+            col, fetch=args.machines_fetch_arch,
+            buildman_path=args.machines_buildman_path)
 
     git_dir = os.path.join(args.git, '.git')
 
diff --git a/tools/buildman/test_machine.py b/tools/buildman/test_machine.py
index 1397a4a76c0..b635d1afb6f 100644
--- a/tools/buildman/test_machine.py
+++ b/tools/buildman/test_machine.py
@@ -172,6 +172,20 @@  sandbox   : /usr/bin/gcc
             'sandbox': '/usr/bin/gcc',
         })
 
+    @mock.patch('buildman.machine._run_ssh')
+    def test_fetch_toolchain_success(self, mock_ssh):
+        """Test successful toolchain fetch"""
+        mock_ssh.return_value = 'Downloading...\nDone'
+        m = machine.Machine('server1')
+        self.assertTrue(m.fetch_toolchain('buildman', 'arm'))
+
+    @mock.patch('buildman.machine._run_ssh')
+    def test_fetch_toolchain_failure(self, mock_ssh):
+        """Test failed toolchain fetch"""
+        mock_ssh.side_effect = machine.MachineError('fetch failed')
+        m = machine.Machine('server1')
+        self.assertFalse(m.fetch_toolchain('buildman', 'arm'))
+
     @mock.patch('buildman.machine._run_ssh')
     def test_weight_calculation(self, mock_ssh):
         """Test weight calculation based on load"""