blob: 8b53553892ebe75f043fd730f0095eba3bb3fbb8 [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generate board-specific scripts for Go compiler testing."""
from __future__ import print_function
import argparse
import getpass
import os
import sys
from cros_utils import command_executer
SUCCESS = 0
DEBUG = False
ARCH_DATA = {'x86_64': 'amd64', 'arm32': 'arm', 'arm64': 'arm64'}
CROS_TOOLCHAIN_DATA = {
'x86_64': 'x86_64-cros-linux-gnu',
'arm32': 'armv7a-cros-linux-gnueabihf',
'arm64': 'aarch64-cros-linux-gnu'
}
GLIBC_DATA = {'x86_64': 'glibc', 'arm32': 'glibc32', 'arm64': 'glibc'}
CONFIG_TEMPLATE = """
Host %s
HostName %s
User root
UserKnownHostsFile /dev/null
BatchMode yes
CheckHostIP no
StrictHostKeyChecking no
IdentityFile %%d/.ssh/testing_rsa
"""
BASE_TEMPLATE = """#!/bin/bash
# Invoke the Go cross compiler for %s.
# Uses ../go_target to add PIE flags.
#
# This is just an example for an %s board.
GOOS="linux" GOARCH="%s" CGO_ENABLED="1" \\
GOROOT="/usr/lib/go/%s" \\
CC="%s-clang" \\
CXX="%s-clang++" \\
exec go_target "$@"
"""
EXEC_TEMPLATE = """#!/bin/bash
# Copy and remotely execute a binary on the %s device.
#
# For this to work, the corresponding entry must exist in
# ~/.ssh/config and the device must already be setup for
# password-less authentication. See setup instructions at
# http://go/chromeos-toolchain-team/go-toolchain
GOOS="linux" GOARCH="%s" \\
GOLOADER="/tmp/%s/ld.so" \\
exec go_target_exec %s "$@"
"""
def log(msg):
if DEBUG:
print(msg)
def WriteFile(file_content, file_name):
with open(file_name, 'w', encoding='utf-8') as out_file:
out_file.write(file_content)
def GenerateGoHelperScripts(ce, arm_board, x86_board, chromeos_root):
keys = ['x86_64', 'arm32', 'arm64']
names = {
'x86_64': x86_board,
'arm64': arm_board,
'arm32': ('%s32' % arm_board)
}
toolchain_dir = os.path.join(chromeos_root, 'src', 'third_party',
'toolchain-utils', 'go', 'chromeos')
for k in keys:
name = names[k]
arch = ARCH_DATA[k]
toolchain = CROS_TOOLCHAIN_DATA[k]
glibc = GLIBC_DATA[k]
base_file = os.path.join(toolchain_dir, ('go_%s' % name))
base_file_content = BASE_TEMPLATE % (name, arch, arch, toolchain, toolchain,
toolchain)
WriteFile(base_file_content, base_file)
cmd = 'chmod 755 %s' % base_file
ce.RunCommand(cmd)
exec_file = os.path.join(toolchain_dir, ('go_%s_exec' % name))
exec_file_content = EXEC_TEMPLATE % (name, arch, glibc, name)
WriteFile(exec_file_content, exec_file)
cmd = 'chmod 755 %s' % exec_file
ce.RunCommand(cmd)
return 0
def UpdateChrootSshConfig(ce, arm_board, arm_dut, x86_board, x86_dut,
chromeos_root):
log('Entering UpdateChrootSshConfig')
# Copy testing_rsa to .ssh and set file protections properly.
user = getpass.getuser()
ssh_dir = os.path.join(chromeos_root, 'chroot', 'home', user, '.ssh')
dest_file = os.path.join(ssh_dir, 'testing_rsa')
src_file = os.path.join(chromeos_root, 'src', 'scripts',
'mod_for_test_scripts', 'testing_rsa')
if not os.path.exists(dest_file):
if os.path.exists(src_file):
cmd = 'cp %s %s' % (src_file, dest_file)
ret = ce.RunCommand(cmd)
if ret != SUCCESS:
print('Error executing "%s". Exiting now...' % cmd)
sys.exit(1)
cmd = 'chmod 600 %s' % dest_file
ret = ce.RunCommand(cmd)
if ret != SUCCESS:
print('Error executing %s; may need to re-run this manually.' % cmd)
else:
print('Cannot find %s; you will need to update testing_rsa by hand.' %
src_file)
else:
log('testing_rsa exists already.')
# Save ~/.ssh/config file, if not already done.
config_file = os.path.expanduser('~/.ssh/config')
saved_config_file = os.path.join(
os.path.expanduser('~/.ssh'), 'config.save.go-scripts')
if not os.path.exists(saved_config_file):
cmd = 'cp %s %s' % (config_file, saved_config_file)
ret = ce.RunCommand(cmd)
if ret != SUCCESS:
print('Error making save copy of ~/.ssh/config. Exiting...')
sys.exit(1)
# Update ~/.ssh/config file
log('Reading ssh config file')
with open(config_file, 'r') as input_file:
config_lines = input_file.read()
x86_host_config = CONFIG_TEMPLATE % (x86_board, x86_dut)
arm_names = '%s %s32' % (arm_board, arm_board)
arm_host_config = CONFIG_TEMPLATE % (arm_names, arm_dut)
config_lines += x86_host_config
config_lines += arm_host_config
log('Writing ~/.ssh/config')
WriteFile(config_lines, config_file)
return 0
def CleanUp(ce, x86_board, arm_board, chromeos_root):
# Find and remove go helper scripts
keys = ['x86_64', 'arm32', 'arm64']
names = {
'x86_64': x86_board,
'arm64': arm_board,
'arm32': ('%s32' % arm_board)
}
toolchain_dir = os.path.join(chromeos_root, 'src', 'third_party',
'toolchain-utils', 'go', 'chromeos')
for k in keys:
name = names[k]
base_file = os.path.join(toolchain_dir, ('go_%s' % name))
exec_file = os.path.join(toolchain_dir, ('go_%s_exec' % name))
cmd = ('rm -f %s; rm -f %s' % (base_file, exec_file))
ce.RunCommand(cmd)
# Restore saved config_file
config_file = os.path.expanduser('~/.ssh/config')
saved_config_file = os.path.join(
os.path.expanduser('~/.ssh'), 'config.save.go-scripts')
if not os.path.exists(saved_config_file):
print('Could not find file: %s; unable to restore ~/.ssh/config .' %
saved_config_file)
else:
cmd = 'mv %s %s' % (saved_config_file, config_file)
ce.RunCommand(cmd)
return 0
def Main(argv):
# pylint: disable=global-statement
global DEBUG
parser = argparse.ArgumentParser()
parser.add_argument('-a', '--arm64_board', dest='arm_board', required=True)
parser.add_argument(
'-b', '--x86_64_board', dest='x86_64_board', required=True)
parser.add_argument(
'-c', '--chromeos_root', dest='chromeos_root', required=True)
parser.add_argument('-x', '--x86_64_dut', dest='x86_64_dut', required=True)
parser.add_argument('-y', '--arm64_dut', dest='arm_dut', required=True)
parser.add_argument(
'-z', '--cleanup', dest='cleanup', default=False, action='store_true')
parser.add_argument(
'-v', '--verbose', dest='verbose', default=False, action='store_true')
options = parser.parse_args(argv[1:])
if options.verbose:
DEBUG = True
if not os.path.exists(options.chromeos_root):
print('Invalid ChromeOS Root: %s' % options.chromeos_root)
ce = command_executer.GetCommandExecuter()
all_good = True
for m in (options.x86_64_dut, options.arm_dut):
cmd = 'ping -c 3 %s > /dev/null' % m
ret = ce.RunCommand(cmd)
if ret != SUCCESS:
print('Machine %s is currently not responding to ping.' % m)
all_good = False
if not all_good:
return 1
if not options.cleanup:
UpdateChrootSshConfig(ce, options.arm_board, options.arm_dut,
options.x86_64_board, options.x86_64_dut,
options.chromeos_root)
GenerateGoHelperScripts(ce, options.arm_board, options.x86_64_board,
options.chromeos_root)
else:
CleanUp(ce, options.x86_64_board, options.arm_board, options.chromeos_root)
return 0
if __name__ == '__main__':
val = Main(sys.argv)
sys.exit(val)