# Copyright 2014 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.

"""Script to run Chrome OS-specific GCE commands ."""

from __future__ import print_function

import logging
import os

from chromite.compute import bot_constants
from chromite.compute import compute_configs
from chromite.compute import gcloud
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import gs


# Supported targets.
TARGETS = (
    'instances',
    'images',
    'disks',
)

# Supported operations.
OPERATIONS = {
    'instances': ('create', 'delete', 'list', 'ssh'),
    'images': ('create', 'delete', 'list'),
    'disks': ('list'),
}


def BotifyInstance(instance, project, zone):
  """Transforms the |instance| to a Chrome OS bot.

  Perform necessary tasks to clone the chromite repostority on the
  |instance| and run setup scripts as BUILDBOT_USER.

  The majority the setup logic is (and should be) in the scripts that
  run directly on the |instance| because `gcloud compute ssh` incurs
  addtional overhead on every invocation. (e.g. instance name to IP
  lookup, copying public key if needed, etc).

  Args:
    instance: Name of the GCE instance.
    project: GCloud Project that the |instance| belongs to.
    zone: Zone of the GCE instance.
  """
  # TODO: To speed this up, we can switch to run remote commands using
  # remote_access.RemoteAgent wrapper. We'd only need to run `gcloud
  # compute ssh` once to initiate the first SSH connection (which
  # copies the public key).
  gcctx = gcloud.GCContext(project, zone=zone)
  gcctx.SSH(instance, cmd='umask 0022')
  # Set up buildbot user and grant it sudo rights.
  gcctx.SSH(instance,
            cmd=('sudo adduser --disabled-password --gecos "" %s'
                 % bot_constants.BUILDBOT_USER))
  gcctx.SSH(instance,
            cmd='sudo adduser %s sudo' % bot_constants.BUILDBOT_USER)
  gcctx.SSH(
      instance,
      cmd=('sudo awk \'BEGIN{print "%%%s ALL=NOPASSWD: ALL" >>"/etc/sudoers"}\''
           % bot_constants.BUILDBOT_USER))

  # Copy bot credentials to a temporay location.
  dest_path = bot_constants.BOT_CREDS_TMP_PATH
  src_path = os.getenv(bot_constants.BOT_CREDS_DIR_ENV_VAR)
  if not src_path:
    raise ValueError('Environment variable %s is not set. This is necessary'
                     'to set up credentials for the bot.'
                     % bot_constants.BOT_CREDS_DIR_ENV_VAR)
  gcctx.CopyFilesToInstance(instance, src_path, dest_path)
  gcctx.SSH(
      instance,
      cmd='sudo chown -R %s:%s %s' % (bot_constants.BUILDBOT_USER,
                                      bot_constants.BUILDBOT_USER,
                                      dest_path))
  # Set the credential files/directories to the correct mode.
  gcctx.SSH(
      instance,
      cmd=r'sudo find %s -type d -exec chmod 700 {} \;' % dest_path)
  gcctx.SSH(
      instance,
      cmd=r'sudo find %s -type f -exec chmod 600 {} \;' % dest_path)

  # Install git to clone chromite.
  base_dir = '/tmp'
  gcctx.SSH(instance, cmd='sudo apt-get install git')
  gcctx.SSH(instance, cmd='cd %s && git clone %s' % (
      base_dir, bot_constants.CHROMITE_URL))

  # Run the setup script as BUILDBOT_USER.
  gcctx.SSH(
      instance,
      cmd='sudo su %s -c %s' % (
          bot_constants.BUILDBOT_USER,
          os.path.join(base_dir, 'chromite', 'compute', 'setup_bot')))


def CreateAndArchiveImageFromInstance(instance, project, zone, image_name):
  """Create an image from the root disk of |instance|.

  This creates the image on the |instance|, archives it to Google
  Storage, and add the image to the Compute Engine.

  The root disk needs to be smaller than 10GB. See requirement in
  https://cloud.google.com/compute/docs/images

  Args:
    instance: Name of the GCE instance.
    project: GCloud Project that the |instance| belongs to.
    zone: Zone of the GCE instance.
    image_name: Name of the image.

  """
  image_name_with_suffix = '%s%s' % (image_name, compute_configs.IMAGE_SUFFIX)
  archive_path = os.path.join(
      compute_configs.GS_IMAGE_ARCHIVE_BASE_URL,
      image_name_with_suffix)
  gsctx = gs.GSContext()
  if gsctx.Exists(archive_path):
    # We should not allow overwriting the existing image.
    cros_build_lib.Die('Image %s already exists!' % archive_path)

  logging.info('Creating image %s', image_name_with_suffix)
  gcctx = gcloud.GCContext(project, zone=zone)

  # Do not include current user's home directory.
  home_dir = gcctx.SSH(instance, cmd='cd ~ && pwd',
                       redirect_stdout=True).output.strip()
  # Create the image. gcimagebundle should have been installed in the
  # base image already.
  output_dir = '/tmp'
  cmd = ['sudo',
         'gcimagebundle',
         '--disk', compute_configs.BOOT_DISK,
         '--root', '/',
         '--output_directory', '/tmp',
         '--output_file_name', image_name_with_suffix,
         '--excludes', home_dir,
         '--loglevel=DEBUG', '--log_file=/tmp/image_bundle.log']
  gcctx.SSH(instance, cmd=' '.join(cmd))

  # Get a temporary Copy of gsutil.
  gcctx.SSH(instance,
            cmd=('curl https://storage.googleapis.com/pub/gsutil.tar.gz'
                 '| tar -xz -C /tmp'))
  # Upload the image to Google Storage.
  src_path = os.path.join(output_dir, image_name_with_suffix)
  gcctx.SSH(
      instance,
      cmd='/tmp/gsutil/gsutil cp %s %s' % (src_path, archive_path))

  # Add the image to the project.
  gcctx.CreateImage(image_name, archive_path)


def CreateImageForCrosBots(project, zone):
  """Create a new image for cros bots."""
  gcctx = gcloud.GCContext(project, zone=zone, quiet=True)
  # The name of the image to create.
  image = compute_configs.DEFAULT_IMAGE_NAME
  # Create a temporary instance and botify it.
  instance = ('chromeos-temp-%s'
              % cros_build_lib.GetRandomString())
  gcctx.CreateInstance(instance, image=compute_configs.DEFAULT_BASE_IMAGE)
  try:
    BotifyInstance(instance, project, zone)
  except:
    # Clean up the temp instance.
    gcctx.DeleteInstance(instance)
    raise

  gcctx.DeleteInstance(instance, keep_disks='boot')
  # By default the name of the boot disk is the same as the name of
  # the instance
  disk = instance
  try:
    # Create image from source disk. By default the name of the boot
    # disk is the same as the name of the instance.
    gcctx.CreateImage(image, disk=disk)
  finally:
    gcctx.DeleteDisk(disk)


def main(argv):
  parser = commandline.ArgumentParser(description=__doc__)

  parser.add_argument(
      'target', choices=TARGETS, help='Operation target')
  parser.add_argument(
      'operation', type=str, help='Operation type')
  parser.add_argument(
      '--project', type=str, default=compute_configs.PROJECT,
      help='Project name')
  parser.add_argument(
      '--instance', type=str, default=None, help='Instance name')
  parser.add_argument(
      '--image', type=str, default=None, help='Image name')
  parser.add_argument(
      '--zone', type=str, default=compute_configs.DEFAULT_ZONE,
      help='Zone to run the command against')
  parser.add_argument(
      '--address', type=str, default=None,
      help='IP to assign to the instance')
  parser.add_argument(
      '--config', type=str, default=None,
      help='Config to create the instance from')
  parser.add_argument(
      '--chromeos', default=False, action='store_true',
      help='Turn on the offical Chrome OS flag (e.g. to create '
           'a new Chrome OS bot image)')

  opts = parser.parse_args(argv)
  opts.Freeze()

  if opts.operation not in OPERATIONS[opts.target]:
    cros_build_lib.Die(
        'Unknown operation %s. Valid operations are %s' % (
            opts.target, OPERATIONS[opts.target]))

  gcctx = gcloud.GCContext(opts.project, zone=opts.zone)
  if opts.target == 'images':
    # Operations against images.
    if opts.operation == 'create':
      if opts.chromeos:
        # Create a new image for Chrome OS bots. The name of the base
        # image and the image to create are defined in compute_configs.
        CreateImageForCrosBots(opts.project, opts.zone)
      else:
        if not opts.image or not opts.instance:
          cros_build_lib.Die(
              'Please specify the name of the instance (--instance) '
              'and the name of the image (--image) to create')
          CreateAndArchiveImageFromInstance(opts.instance, opts.project,
                                            opts.zone, opts.image)
    elif opts.operation == 'delete':
      gcctx.DeleteImage(opts.image)
    elif opts.operation == 'list':
      gcctx.ListImages()

  elif opts.target == 'instances':
    # Operations against instances.
    if opts.operation == 'create':
      if not opts.instance:
        cros_build_lib.Die('Please specify the instance name (--instance)')

      if ((not opts.image and not opts.config) or
          (opts.image and opts.config)):
        cros_build_lib.Die(
            'One and only one of the two options should be specified: '
            'source image (--image) or the builder (--config)')
      if opts.image:
        gcctx.CreateInstance(opts.instance, image=opts.image)
      elif opts.config:
        config = compute_configs.configs.get(opts.config, None)
        if not config:
          cros_build_lib.Die('Unkown config %s' % opts.config)
        gcctx.CreateInstance(opts.instance, address=opts.address, **config)
    elif opts.operation == 'delete':
      cros_build_lib.Die('Please specify the instance name (--instance)')
      gcctx.DeleteInstance(opts.instance)
    elif opts.operation == 'list':
      gcctx.ListInstances()
    elif opts.operation == 'ssh':
      if not opts.instance:
        cros_build_lib.Die('Please specify the instance with --instance')
      gcctx.SSH(opts.instance)

  elif opts.target == 'disks':
    if opts.operation == 'list':
      gcctx.ListDisks()
