# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
This recipe is used to flash a CrOS DUT on a Chromium bot.

This essentially calls out to the cros-sdk's flash tool (located at
https://codesearch.chromium.org/chromium/src/third_party/chromite/cli/flash.py).

That tool however has a dependency on the cros SDK's chroot (see
https://chromium.googlesource.com/chromiumos/docs/+/master/developer_guide.md#Create-a-chroot
for more info). Though it's often used in CrOS development, the chroot isn't
found in Chromium development at all, and has very limited support on Chromium
bots. Consequently, this recipe will take care of setting it up prior to
flashing the DUT. The basic steps of this recipe are:

- Fetch a full ChromiumOS checkout via repo. The checkout will be placed in a
  named cache for subsequent re-use.
- Build the chroot.
- Enter the chroot and flash the device.
"""

DEPS = [
  'chromite',
  'depot_tools/gsutil',
  'recipe_engine/context',
  'recipe_engine/path',
  'recipe_engine/platform',
  'recipe_engine/properties',
  'recipe_engine/python',
  'recipe_engine/raw_io',
  'recipe_engine/step',
  'recipe_engine/tempfile',
  'repo',
]

# This is a special hostname that resolves to a different DUT depending on
# which swarming bot you're on.
CROS_DUT_HOSTNAME = 'variable_chromeos_device_hostname'

# Default password for root on a device running a test image. The contents of
# this password are public and not confidential.
CROS_SSH_PASSWORD = 'test0000'

# Path to an RSA key pair used for SSH auth with the DUT.
SWARMING_BOT_SSH_ID = '/b/id_rsa'


def RunSteps(api):
  gs_image_bucket = api.properties.get('gs_image_bucket')
  gs_image_path = api.properties.get('gs_image_path')
  if not gs_image_bucket or not gs_image_path:
    api.python.failing_step('unknown GS image URL',
        'Must pass the Google Storage URL for the image to flash via the '
        '"gs_image_bucket" and "gs_image_path" recipe properties.')

  # After flashing, the host's ssh identity is no longer authorized with the
  # DUT, so we'll need to add it back. The host's identity is an ssh key file
  # located at SWARMING_BOT_SSH_ID that the swarming bot generates at start-up.
  # Ensure that file exists on the bot.
  api.path.mock_add_paths(SWARMING_BOT_SSH_ID)
  api.path.mock_add_paths(SWARMING_BOT_SSH_ID + '.pub')
  if (not api.path.exists(SWARMING_BOT_SSH_ID) or
      not api.path.exists(SWARMING_BOT_SSH_ID + '.pub')):
    api.python.failing_step('host ssh ID not found',  # pragma: no cover
        'The env var CROS_SSH_ID_FILE_PATH (%s) must be set and point to a ssh '
        'key pair to use for authentication with the DUT.' % ssh_id_file)

  # Download (and optionally extract) the CrOS image in a temp dir.
  with api.tempfile.temp_dir("cros_flash") as tmp_dir:
    if gs_image_path.endswith('.tar.xz'):
      dest = tmp_dir.join('chromiumos_image.tar.xz')
      api.gsutil.download(
          gs_image_bucket, gs_image_path, dest, name='download image')
      with api.context(cwd=tmp_dir):
        extract_result = api.step(
            'extract image', ['/bin/tar', '-xvf', dest],
            stdout=api.raw_io.output('out'))
      # Pull the name of the exracted file from tar's stdout.
      img_path = tmp_dir.join(extract_result.stdout.strip())
    elif gs_image_path.endswith('.bin'):
      img_path = tmp_dir.join('chromiumos_image.bin')
      api.gsutil.download(
          gs_image_bucket, gs_image_path, img_path, name='download image')
    else:
      api.python.failing_step('unknown image format',
          'Image file must end in either ".bin" or ".tar.xz".')

    # Move into the named cache, and fetch a full ChromiumOS checkout.
    cros_checkout_path = api.path['cache'].join('builder')
    with api.context(cwd=cros_checkout_path):
      api.chromite.checkout(repo_sync_args=['-j4'])

      # Pass in --nouse-image below so the chroot is simply encased in a dir.
      # It'll otherwise try creating and mounting an image file (which can be a
      # 500GB sparse file).
      api.chromite.cros_sdk(
          'build chroot', ['exit'],
          chroot_cmd=cros_checkout_path.join('chromite', 'bin', 'cros_sdk'),
          args=['--nouse-image', '--create', '--debug'])

      # chromite's own virtual env setup conflicts with vpython, so temporarily
      # subvert vpython for the duration of the flash.
      with api.chromite.with_system_python():
        cros_tool_path = cros_checkout_path.join('chromite', 'bin', 'cros')
        arg_list = [
          'flash',
          CROS_DUT_HOSTNAME,
          img_path,
          '--disable-rootfs-verification',  # Needed to add ssh identity below.
          '--force',  # Force yes to all Y/N prompts.
          '--debug',  # More verbose logging.
        ]
        api.python('flash DUT', cros_tool_path, arg_list)

  # Reauthorize the host's ssh identity with the DUT via ssh-copy-id, using
  # sshpass to pass in the root password.
  cmd = [
     '/usr/bin/sshpass',
     '-p', CROS_SSH_PASSWORD,
     '/usr/bin/ssh-copy-id', '-i', SWARMING_BOT_SSH_ID + '.pub',
     'root@' + CROS_DUT_HOSTNAME,
  ]
  api.step('reauthorize DUT ssh access', cmd)


def GenTests(api):
  yield (
    api.test('basic_test') +
    api.platform('linux', 64) +
    api.properties(
        gs_image_bucket='cros-image-bucket',
        gs_image_path='some/image/path.bin',
    )
  )

  yield (
    api.test('basic_test_with_extract') +
    api.platform('linux', 64) +
    api.properties(
        gs_image_bucket='cros-image-bucket',
        gs_image_path='some/image/path.tar.xz',
    )
  )

  yield (
    api.test('unknown_image_format') +
    api.platform('linux', 64) +
    api.properties(
        gs_image_bucket='cros-image-bucket',
        gs_image_path='some/image/path.exe',
    )
  )

  yield (
    api.test('missing_props') +
    api.platform('linux', 64) +
    api.properties()
  )
