# -*- 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.
"""Library to generate a DLC (Downloadable Content) artifact."""

from __future__ import division
from __future__ import print_function

import hashlib
import json
import math
import os
import re
import shutil
import sys

from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import osutils
from chromite.lib import pformat

from chromite.licensing import licenses_lib
from chromite.scripts import cros_set_lsb_release

assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'

DLC_META_DIR = 'opt/google/dlc/'
DLC_TMP_META_DIR = 'meta'
DLC_BUILD_DIR = 'build/rootfs/dlc/'
LICENSE = 'LICENSE'
LSB_RELEASE = 'etc/lsb-release'
DLC_IMAGE = 'dlc.img'
IMAGELOADER_JSON = 'imageloader.json'
EBUILD_PARAMETERS = 'ebuild_parameters.json'

# This file has major and minor version numbers that the update_engine client
# supports. These values are needed for generating a delta/full payload.
UPDATE_ENGINE_CONF = 'etc/update_engine.conf'

_EXTRA_RESOURCES = (UPDATE_ENGINE_CONF,)
# The following boards don't have AppIds, but we allow DLCs to be generated for
# those boards for testing purposes.
_TEST_BOARDS_ALLOWLIST = ('amd64-generic', 'arm-generic', 'galaxy')

DLC_ID_KEY = 'DLC_ID'
DLC_PACKAGE_KEY = 'DLC_PACKAGE'
DLC_NAME_KEY = 'DLC_NAME'
DLC_APPID_KEY = 'DLC_RELEASE_APPID'

SQUASHFS_TYPE = 'squashfs'
EXT4_TYPE = 'ext4'

USED_BY_USER = 'user'
USED_BY_SYSTEM = 'system'

_MAX_ID_NAME = 40

_IMAGE_SIZE_NEARING_RATIO = 1.05
_IMAGE_SIZE_GROWTH_RATIO = 1.2

def HashFile(file_path):
  """Calculate the sha256 hash of a file.

  Args:
    file_path: (str) path to the file.

  Returns:
    [str]: The sha256 hash of the file.
  """
  sha256 = hashlib.sha256()
  with open(file_path, 'rb') as f:
    for b in iter(lambda: f.read(2048), b''):
      sha256.update(b)
  return sha256.hexdigest()


def GetValueInJsonFile(json_path, key, default_value=None):
  """Reads file containing JSON and returns value or default_value for key.

  Args:
    json_path: (str) File containing JSON.
    key: (str) The desired key to lookup.
    default_value: (default:None) The default value returned in case of missing
      key.
  """
  with open(json_path) as fd:
    return json.load(fd).get(key, default_value)


class EbuildParams(object):
  """Object to store and retrieve DLC ebuild parameters.

  Attributes:
    dlc_id: (str) DLC ID.
    dlc_package: (str) DLC package.
    fs_type: (str) file system type.
    pre_allocated_blocks: (int) number of blocks pre-allocated on device.
    version: (str) DLC version.
    name: (str) DLC name.
    description: (str) DLC description.
    preload: (bool) allow for preloading DLC.
    mount_file_required: (bool) allow for mount file generation for DLC.
    used_by: (str) The user of this DLC, e.g. "system" or "user"
    fullnamerev: (str) The full package & version name.
  """

  def __init__(self, dlc_id, dlc_package, fs_type, pre_allocated_blocks,
               version, name, description, preload, used_by,
               mount_file_required, fullnamerev):
    self.dlc_id = dlc_id
    self.dlc_package = dlc_package
    self.fs_type = fs_type
    self.pre_allocated_blocks = pre_allocated_blocks
    self.version = version
    self.name = name
    self.description = description
    self.preload = preload
    self.used_by = used_by
    self.mount_file_required = mount_file_required
    self.fullnamerev = fullnamerev

  def StoreDlcParameters(self, install_root_dir, sudo):
    """Store DLC parameters defined in the ebuild.

    Store DLC parameters defined in the ebuild in a temporary file so they can
    be retrieved in the build_image phase.

    Args:
      install_root_dir: (str) The path to the root installation directory.
      sudo: (bool) Use sudo to write the file.
    """
    ebuild_params_path = EbuildParams.GetParamsPath(install_root_dir,
                                                    self.dlc_id,
                                                    self.dlc_package)
    osutils.WriteFile(ebuild_params_path,
                      json.dumps(self.__dict__),
                      makedirs=True, sudo=sudo)

  @staticmethod
  def GetParamsPath(install_root_dir, dlc_id, dlc_package):
    """Get the path to the file storing the ebuild parameters.

    Args:
      install_root_dir: (str) The path to the root installation directory.
      dlc_id: (str) DLC ID.
      dlc_package: (str) DLC package.

    Returns:
      [str]: Path to |EBUILD_PARAMETERS|.
    """
    return os.path.join(install_root_dir, DLC_BUILD_DIR, dlc_id, dlc_package,
                        EBUILD_PARAMETERS)

  @classmethod
  def LoadEbuildParams(cls, sysroot, dlc_id, dlc_package):
    """Read the stored ebuild parameters file and return a class instance.

    Args:
      dlc_id: (str) DLC ID.
      dlc_package: (str) DLC package.
      sysroot: (str) The path to the build root directory.

    Returns:
      [bool] : True if |ebuild_params_path| exists, False otherwise.
    """
    path = cls.GetParamsPath(sysroot, dlc_id, dlc_package)
    if not os.path.exists(path):
      return None

    with open(path, 'rb') as fp:
      return cls(**json.load(fp))

  def __str__(self):
    return str(self.__dict__)


class DlcGenerator(object):
  """Object to generate DLC artifacts."""
  # Block size for the DLC image.
  # We use 4K for various reasons:
  # 1. it's what imageloader (linux kernel) supports.
  # 2. it's what verity supports.
  _BLOCK_SIZE = 4096
  # Blocks in the initial sparse image.
  _BLOCKS = 500000
  # Version of manifest file.
  _MANIFEST_VERSION = 1

  # The DLC root path inside the DLC module.
  _DLC_ROOT_DIR = 'root'

  def __init__(self, ebuild_params, sysroot, install_root_dir, board,
               src_dir=None):
    """Object initializer.

    Args:
      sysroot: (str) The path to the build root directory.
      install_root_dir: (str) The path to the root installation directory.
      ebuild_params: (EbuildParams) Ebuild variables.
      board: (str) The target board we are building for.
      src_dir: (str) Optional path to the DLC source root directory. When None,
               the default directory in |DLC_BUILD_DIR| is used.
    """
    # Use a temporary directory to avoid having to use sudo every time we write
    # into the build directory.
    self.temp_root = osutils.TempDir(prefix='dlc', sudo_rm=True)
    self.src_dir = src_dir
    self.sysroot = sysroot
    self.install_root_dir = install_root_dir
    self.board = board
    self.ebuild_params = ebuild_params
    # If the client is not overriding the src_dir, use the default one.
    if not self.src_dir:
      self.src_dir = os.path.join(self.sysroot, DLC_BUILD_DIR,
                                  self.ebuild_params.dlc_id,
                                  self.ebuild_params.dlc_package,
                                  self._DLC_ROOT_DIR)

    self.image_dir = os.path.join(self.temp_root.tempdir,
                                  DLC_BUILD_DIR,
                                  self.ebuild_params.dlc_id,
                                  self.ebuild_params.dlc_package)

    self.meta_dir = os.path.join(self.image_dir, DLC_TMP_META_DIR)

    # Create path for all final artifacts.
    self.dest_image = os.path.join(self.image_dir, DLC_IMAGE)
    self.dest_table = os.path.join(self.meta_dir, 'table')
    self.dest_imageloader_json = os.path.join(self.meta_dir, IMAGELOADER_JSON)

    # Log out the member variable values initially set.
    logging.debug('Initial internal values of DlcGenerator: %s',
                  repr({k:str(i) for k, i in self.__dict__.items()}))

  def CopyTempContentsToBuildDir(self):
    """Copy the temp files to the build directory using sudo."""
    src = self.temp_root.tempdir.rstrip('/') + '/.'
    dst = self.install_root_dir
    logging.info(
        'Copy files from temporary directory (%s) to build directory (%s).',
        src, dst)
    cros_build_lib.sudo_run(['cp', '-dR', src, dst])

  def SquashOwnerships(self, path):
    """Squash the owernships & permissions for files.

    Args:
      path: (str) path that contains all files to be processed.
    """
    cros_build_lib.sudo_run(['chown', '-R', '0:0', path])
    cros_build_lib.sudo_run([
        'find', path, '-exec', 'touch', '-h', '-t', '197001010000.00', '{}', '+'
    ])

  def CreateExt4Image(self):
    """Create an ext4 image."""
    with osutils.TempDir(prefix='dlc_') as temp_dir:
      mount_point = os.path.join(temp_dir, 'mount_point')
      # Create the directory where the image is located if it doesn't exist.
      osutils.SafeMakedirs(os.path.split(self.dest_image)[0])
      # Create a raw image file.
      with open(self.dest_image, 'w') as f:
        f.truncate(self._BLOCKS * self._BLOCK_SIZE)
      # Create an ext4 file system on the raw image.
      cros_build_lib.run([
          '/sbin/mkfs.ext4', '-b',
          str(self._BLOCK_SIZE), '-O', '^has_journal', self.dest_image
      ],
                         capture_output=True)
      # Create the mount_point directory.
      osutils.SafeMakedirs(mount_point)
      # Mount the ext4 image.
      osutils.MountDir(self.dest_image, mount_point, mount_opts=('loop', 'rw'))

      try:
        self.SetupDlcImageFiles(mount_point)
      finally:
        # Unmount the ext4 image.
        osutils.UmountDir(mount_point)
      # Shrink to minimum size.
      cros_build_lib.run(['/sbin/e2fsck', '-y', '-f', self.dest_image],
                         capture_output=True)
      cros_build_lib.run(['/sbin/resize2fs', '-M', self.dest_image],
                         capture_output=True)

  def CreateSquashfsImage(self):
    """Create a squashfs image."""
    with osutils.TempDir(prefix='dlc_') as temp_dir:
      squashfs_root = os.path.join(temp_dir, 'squashfs-root')
      self.SetupDlcImageFiles(squashfs_root)

      cros_build_lib.run([
          'mksquashfs', squashfs_root, self.dest_image, '-4k-align', '-noappend'
      ],
                         capture_output=True)

      # We changed the ownership and permissions of the squashfs_root
      # directory. Now we need to remove it manually.
      osutils.RmDir(squashfs_root, sudo=True)

  def SetupDlcImageFiles(self, dlc_dir):
    """Prepares the directory dlc_dir with all the files a DLC needs.

    Args:
      dlc_dir: (str) The path to where to setup files inside the DLC.
    """
    dlc_root_dir = os.path.join(dlc_dir, self._DLC_ROOT_DIR)
    osutils.SafeMakedirs(dlc_root_dir)
    osutils.CopyDirContents(self.src_dir, dlc_root_dir, symlinks=True)
    self.PrepareLsbRelease(dlc_dir)
    self.AddLicensingFile(dlc_dir)
    self.CollectExtraResources(dlc_dir)
    self.SquashOwnerships(dlc_dir)

  def PrepareLsbRelease(self, dlc_dir):
    """Prepare the file /etc/lsb-release in the DLC module.

    This file is used dropping some identification parameters for the DLC.

    Args:
      dlc_dir: (str) The path to the mounted point during image creation.
    """
    app_id = None
    platform_lsb_rel_path = os.path.join(self.sysroot, LSB_RELEASE)
    if os.path.isfile(platform_lsb_rel_path):
      # Reading the platform APPID and creating the DLC APPID.
      platform_lsb_release = osutils.ReadFile(platform_lsb_rel_path)
      for line in platform_lsb_release.split('\n'):
        if line.startswith(cros_set_lsb_release.LSB_KEY_APPID_RELEASE):
          app_id = line.split('=')[1]

    if app_id is None and self.board not in _TEST_BOARDS_ALLOWLIST:
      raise Exception(
          '%s does not have a valid key %s' %
          (platform_lsb_rel_path, cros_set_lsb_release.LSB_KEY_APPID_RELEASE))

    fields = (
        (DLC_ID_KEY, self.ebuild_params.dlc_id),
        (DLC_PACKAGE_KEY, self.ebuild_params.dlc_package),
        (DLC_NAME_KEY, self.ebuild_params.name),
        # The DLC appid is generated by concatenating the platform appid with
        # the DLC ID using an underscore. This pattern should never be changed
        # once set otherwise it can break a lot of things!
        (DLC_APPID_KEY, '%s_%s' % (app_id if app_id else '',
                                   self.ebuild_params.dlc_id)),
    )

    lsb_release = os.path.join(dlc_dir, LSB_RELEASE)
    osutils.SafeMakedirs(os.path.dirname(lsb_release))
    content = ''.join('%s=%s\n' % (k, v) for k, v in fields)
    osutils.WriteFile(lsb_release, content)

  def AddLicensingFile(self, dlc_dir):
    """Add the licensing file for this DLC.

    Args:
      dlc_dir: (str) The path to the mounted point during image creation.
    """
    if not self.ebuild_params.fullnamerev:
      return

    sysroot = cros_build_lib.GetSysroot(self.board)
    licensing = licenses_lib.Licensing(sysroot,
                                       [self.ebuild_params.fullnamerev], True)
    licensing.LoadPackageInfo()
    licensing.ProcessPackageLicenses()
    license_path = os.path.join(dlc_dir, LICENSE)
    # The first (and only) item contains the values for |self.fullnamerev|.
    _, license_txt = next(iter(licensing.GenerateLicenseText().items()))
    osutils.WriteFile(license_path, license_txt)

  def CollectExtraResources(self, dlc_dir):
    """Collect the extra resources needed by the DLC module.

    Look at the documentation around _EXTRA_RESOURCES.

    Args:
      dlc_dir: (str) The path to the mounted point during image creation.
    """
    for r in _EXTRA_RESOURCES:
      source_path = os.path.join(self.sysroot, r)
      target_path = os.path.join(dlc_dir, r)
      osutils.SafeMakedirs(os.path.dirname(target_path))
      shutil.copyfile(source_path, target_path)

  def CreateImage(self):
    """Create the image and copy the DLC files to it."""
    logging.info('Creating the DLC image.')
    if self.ebuild_params.fs_type == EXT4_TYPE:
      self.CreateExt4Image()
    elif self.ebuild_params.fs_type == SQUASHFS_TYPE:
      self.CreateSquashfsImage()
    else:
      raise ValueError('Wrong fs type: %s used:' % self.ebuild_params.fs_type)

  def VerifyImageSize(self):
    """Verify the image can fit to the reserved file."""
    logging.info('Verifying the DLC image size.')
    image_bytes = os.path.getsize(self.dest_image)
    preallocated_bytes = (self.ebuild_params.pre_allocated_blocks *
                          self._BLOCK_SIZE)
    # Verifies the actual size of the DLC image is NOT larger than the
    # preallocated space.
    if preallocated_bytes < image_bytes:
      raise ValueError(
          'The DLC_PREALLOC_BLOCKS (%s) value set in DLC ebuild resulted in a '
          'max size of DLC_PREALLOC_BLOCKS * 4K (%s) bytes the DLC image is '
          'allowed to occupy. The value is smaller than the actual image size '
          '(%s) required. Increase DLC_PREALLOC_BLOCKS in your ebuild to at '
          'least %d.' %
          (self.ebuild_params.pre_allocated_blocks, preallocated_bytes,
           image_bytes, self.GetOptimalImageBlockSize(image_bytes)))

    image_size_ratio = preallocated_bytes / image_bytes

    # Warn if the DLC image size is nearing the preallocated size.
    if image_size_ratio <= _IMAGE_SIZE_NEARING_RATIO:
      logging.warning(
          'The %s DLC image size (%s) is nearing the preallocated size (%s).',
          self.ebuild_params.dlc_id, image_bytes, preallocated_bytes)

    # Warn if the DLC preallocated size is too much.
    if image_size_ratio >= _IMAGE_SIZE_GROWTH_RATIO:
      logging.warning(
          'The %s DLC image size (%s) is significantly less than the '
          'preallocated size (%s). Reduce the DLC_PREALLOC_BLOCKS in your '
          'ebuild', self.ebuild_params.dlc_id, image_bytes, preallocated_bytes)

  def GetOptimalImageBlockSize(self, image_bytes):
    """Given the image bytes, get the least amount of blocks required."""
    return int(math.ceil(image_bytes / self._BLOCK_SIZE))

  def GetImageloaderJsonContent(self, image_hash, table_hash, blocks):
    """Return the content of imageloader.json file.

    Args:
      image_hash: (str) sha256 hash of the DLC image.
      table_hash: (str) sha256 hash of the DLC table file.
      blocks: (int) number of blocks in the DLC image.

    Returns:
      [str]: content of imageloader.json file.
    """
    return {
        'fs-type': self.ebuild_params.fs_type,
        'id': self.ebuild_params.dlc_id,
        'package': self.ebuild_params.dlc_package,
        'image-sha256-hash': image_hash,
        'image-type': 'dlc',
        'is-removable': True,
        'manifest-version': self._MANIFEST_VERSION,
        'name': self.ebuild_params.name,
        'description': self.ebuild_params.description,
        'pre-allocated-size':
            str(self.ebuild_params.pre_allocated_blocks * self._BLOCK_SIZE),
        'size': str(blocks * self._BLOCK_SIZE),
        'table-sha256-hash': table_hash,
        'version': self.ebuild_params.version,
        'preload-allowed': self.ebuild_params.preload,
        'used-by': self.ebuild_params.used_by,
        'mount-file-required': self.ebuild_params.mount_file_required,
    }

  def GenerateVerity(self):
    """Generate verity parameters and hashes for the image."""
    logging.info('Generating DLC image verity.')
    with osutils.TempDir(prefix='dlc_') as temp_dir:
      hash_tree = os.path.join(temp_dir, 'hash_tree')
      # Get blocks in the image.
      blocks = math.ceil(os.path.getsize(self.dest_image) / self._BLOCK_SIZE)
      result = cros_build_lib.run([
          'verity', 'mode=create', 'alg=sha256', 'payload=' + self.dest_image,
          'payload_blocks=' + str(blocks), 'hashtree=' + hash_tree,
          'salt=random'
      ],
                                  capture_output=True)
      table = result.output

      # Append the merkle tree to the image.
      osutils.WriteFile(
          self.dest_image, osutils.ReadFile(hash_tree, mode='rb'), mode='a+b')

      # Write verity parameter to table file.
      osutils.WriteFile(self.dest_table, table, mode='wb')

      # Compute image hash.
      image_hash = HashFile(self.dest_image)
      table_hash = HashFile(self.dest_table)
      # Write image hash to imageloader.json file.
      blocks = math.ceil(os.path.getsize(self.dest_image) / self._BLOCK_SIZE)
      imageloader_json_content = self.GetImageloaderJsonContent(
          image_hash, table_hash, int(blocks))
      pformat.json(imageloader_json_content, fp=self.dest_imageloader_json)

  def GenerateDLC(self):
    """Generate a DLC artifact."""
    # Create directories.
    osutils.SafeMakedirs(self.image_dir)
    osutils.SafeMakedirs(self.meta_dir)

    # Create the image into |self.temp_root| and copy the DLC files to it.
    self.CreateImage()
    # Verify the image created is within pre-allocated size.
    self.VerifyImageSize()
    # Generate hash tree and other metadata and save them under
    # |self.temp_root|.
    self.GenerateVerity()
    # Copy the files from |self.temp_root| into the build directory.
    self.CopyTempContentsToBuildDir()

    # Now that the image was successfully generated, delete |ebuild_params_path|
    # to indicate that the image in the build directory is in sync with the
    # files installed during the build_package phase.
    ebuild_params_path = EbuildParams.GetParamsPath(
        self.sysroot, self.ebuild_params.dlc_id, self.ebuild_params.dlc_package)
    osutils.SafeUnlink(ebuild_params_path, sudo=True)


def IsDlcPreloadingAllowed(dlc_id, dlc_build_dir):
  """Validates that DLC and it's packages all were built with DLC_PRELOAD=true.

  Args:
    dlc_id: (str) DLC ID.
    dlc_build_dir: (str) the root path where DLC build files reside.
  """

  dlc_id_meta_dir = os.path.join(dlc_build_dir, dlc_id)
  if not os.path.exists(dlc_id_meta_dir):
    logging.error('DLC build directory (%s) does not exist for preloading '
                  'check, will not preload', dlc_id_meta_dir)
    return False

  packages = os.listdir(dlc_id_meta_dir)
  if not packages:
    logging.error('DLC ID build directory (%s) does not have any '
                  'packages, will not preload.', dlc_id_meta_dir)
    return False

  for package in packages:
    image_loader_json = os.path.join(dlc_id_meta_dir, package, DLC_TMP_META_DIR,
                                     IMAGELOADER_JSON)
    if not os.path.exists(image_loader_json):
      logging.error('DLC metadata file (%s) does not exist, will not preload.',
                    image_loader_json)
      return False
    if not GetValueInJsonFile(json_path=image_loader_json,
                              key='preload-allowed', default_value=False):
      return False
  # All packages support preload.
  return True


def InstallDlcImages(sysroot, board, dlc_id=None, install_root_dir=None,
                     preload=False, rootfs=None, src_dir=None):
  """Copies all DLC image files into the images directory.

  Copies the DLC image files in the given build directory into the given DLC
  image directory. If the DLC build directory does not exist, or there is no DLC
  for that board, this function does nothing.

  Args:
    sysroot: Path to directory containing DLC images, e.g /build/<board>.
    board: The target board we are building for.
    dlc_id: (str) DLC ID. If None, all the DLCs will be installed.
    install_root_dir: Path to DLC output directory, e.g.
      src/build/images/<board>/<version>. If None, the image will be generated
      but will not be copied to a destination.
    preload: When true, only copies DLC(s) if built with DLC_PRELOAD=true.
    rootfs: (str) Path to the platform rootfs.
    src_dir: (str) Path to the DLC source root directory.
  """
  dlc_build_dir = os.path.join(sysroot, DLC_BUILD_DIR)
  if not os.path.exists(dlc_build_dir):
    logging.info('DLC build directory (%s) does not exist, ignoring.',
                 dlc_build_dir)
    return

  if dlc_id is not None:
    if not os.path.exists(os.path.join(dlc_build_dir, dlc_id)):
      raise Exception(
          'DLC "%s" does not exist in the build directory %s.' %
          (dlc_id, dlc_build_dir))
    dlc_ids = [dlc_id]
  else:
    # Process all DLCs.
    dlc_ids = os.listdir(dlc_build_dir)
    if not dlc_ids:
      logging.info('There are no DLC(s) to copy to output, ignoring.')
      return

    logging.info('Detected the following DLCs: %s', ', '.join(dlc_ids))

  for d_id in dlc_ids:
    dlc_id_path = os.path.join(dlc_build_dir, d_id)
    dlc_packages = [direct for direct in os.listdir(dlc_id_path)
                    if os.path.isdir(os.path.join(dlc_id_path, direct))]
    for d_package in dlc_packages:
      logging.info('Building image: DLC %s', d_id)
      params = EbuildParams.LoadEbuildParams(sysroot=sysroot, dlc_id=d_id,
                                             dlc_package=d_package)
      # Because portage sandboxes every ebuild package during build_packages
      # phase, we cannot delete the old image during that phase, but we can use
      # the existence of the file |EBUILD_PARAMETERS| to know if the image
      # has to be generated or not.
      if not params:
        logging.info('The ebuild parameters file (%s) for DLC (%s) does not '
                     'exist. This means that the image was already '
                     'generated and there is no need to create it again.',
                     EbuildParams.GetParamsPath(sysroot, d_id, d_package), d_id)
      else:
        dlc_generator = DlcGenerator(
            src_dir=src_dir,
            sysroot=sysroot,
            install_root_dir=sysroot,
            board=board,
            ebuild_params=params)
        dlc_generator.GenerateDLC()

      # Copy the dlc images to install_root_dir.
      if install_root_dir:
        if preload and not IsDlcPreloadingAllowed(d_id, dlc_build_dir):
          logging.info('Skipping installation of DLC %s because the preload '
                       'flag is set and the DLC does not support preloading.',
                       d_id)
        else:
          osutils.SafeMakedirsNonRoot(install_root_dir)
          install_dlc_dir = os.path.join(install_root_dir, d_id, d_package)
          osutils.SafeMakedirsNonRoot(install_dlc_dir)
          source_dlc_dir = os.path.join(dlc_build_dir, d_id, d_package)
          for filepath in (os.path.join(source_dlc_dir, fname) for fname in
                           os.listdir(source_dlc_dir) if
                           fname.endswith('.img')):
            logging.info('Copying DLC(%s) image from %s to %s: ', d_id,
                         filepath, install_dlc_dir)
            shutil.copy(filepath, install_dlc_dir)
            logging.info('Done copying DLC to %s.', install_dlc_dir)
      else:
        logging.info('install_root_dir value was not provided. Copying dlc'
                     ' image skipped.')

      # Create metadata directory in rootfs.
      if rootfs:
        meta_rootfs = os.path.join(rootfs, DLC_META_DIR, d_id, d_package)
        osutils.SafeMakedirs(meta_rootfs, sudo=True)
        # Copy the metadata files to rootfs.
        meta_dir_src = os.path.join(dlc_build_dir, d_id, d_package,
                                    DLC_TMP_META_DIR)
        logging.info('Copying DLC(%s) metadata from %s to %s: ', d_id,
                     meta_dir_src, meta_rootfs)
        # Use sudo_run since osutils.CopyDirContents doesn't support sudo.
        cros_build_lib.sudo_run(['cp', '-dR',
                                 meta_dir_src.rstrip('/') + '/.',
                                 meta_rootfs], print_cmd=False, stderr=True)

      else:
        logging.info('rootfs value was not provided. Copying metadata skipped.')

  logging.info('Done installing DLCs.')


def ValidateDlcIdentifier(name):
  """Validates the DLC identifiers like ID and package names.

  The name specifications are:
    - No underscore.
    - First character should be only alphanumeric.
    - Other characters can be alphanumeric and '-' (dash).
    - Maximum length of 40 (_MAX_ID_NAME) characters.

  For more info see:
  https://chromium.googlesource.com/chromiumos/platform2/+/master/dlcservice/docs/developer.md#create-a-dlc-module

  Args:
    name: The value of the string to be validated.
  """
  errors = []
  if not name:
    errors.append('Must not be empty.')
  if not name[0].isalnum():
    errors.append('Must start with alphanumeric character.')
  if not re.match(r'^[a-zA-Z0-9][a-zA-Z0-9-]*$', name):
    errors.append('Must only use alphanumeric and - (dash).')
  if len(name) > _MAX_ID_NAME:
    errors.append('Must be within %d characters.' % _MAX_ID_NAME)

  if errors:
    msg = '%s is invalid:\n%s' % (name, '\n'.join(errors))
    raise Exception(msg)
