def METHOD_NAME():
  # Get Parameters.
  build_date = utils.GetMetadataAttribute(
      'build_date', raise_on_not_found=True)
  debian_cloud_images_version = '889ffb24546d6270eabb4e68823ebc75501ddccd'
  debian_version = utils.GetMetadataAttribute(
      'debian_version', raise_on_not_found=True)
  outs_path = utils.GetMetadataAttribute('daisy-outs-path',
                                         raise_on_not_found=True)
  logging.info('debian-cloud-images version: %s' % debian_cloud_images_version)
  logging.info('debian version: %s' % debian_version)
  # force an apt-get update before next install
  utils.AptGetInstall.first_run = True
  utils.AptGetInstall(['fai-server', 'fai-setup-storage'])
  # Download and setup debian's debian-cloud-images scripts.
  url_params = {
      'project': 'debian-cloud-images',
      'version': debian_cloud_images_version,
  }
  url_params['filename'] = '%(project)s-%(version)s' % url_params
  url = ('https://salsa.debian.org/cloud-team/'
         '%(project)s/-/archive/%(version)s/%(filename)s.tar.gz' % url_params)
  logging.info('Downloading %(project)s at version %(version)s', url_params)
  urllib.request.urlretrieve(url, 'fci.tar.gz')
  with tarfile.open('fci.tar.gz') as tar:
    tar.extractall()
  logging.info('Downloaded and extracted %s.', url)
  work_dir = url_params['filename']
  config_space = (os.getcwd() + '/' + work_dir + '/config_space/'
                  + debian_version + '/')
  # Remove upstream test cases that won't work here.
  os.remove(config_space + 'hooks/tests.BASE')
  # Copy our classes to the FAI config space
  mycopytree('/files/fai_config', config_space)
  # Set scripts executable (daisy doesn't preserve this)
  os.chmod(config_space + 'scripts/BOOKWORM/10-clean', 0o755)
  os.chmod(config_space + 'scripts/GCE_CLEAN/10-gce-clean', 0o755)
  os.chmod(config_space + 'scripts/GCE_SPECIFIC/12-sshd', 0o755)
  os.chmod(config_space + 'hooks/repository.GCE_SPECIFIC', 0o755)
  os.chmod(config_space + 'hooks/configure.GCE_SPECIFIC', 0o755)
  # Config fai-tool
  # Base classes used for everything
  fai_classes = ['BASE', 'DEBIAN', 'CLOUD', 'GCE', 'EXTRAS', 'IPV6_DHCP',
                 'GCE_SPECIFIC', 'GCE_CLEAN', 'LINUX_VARIANT_CLOUD']
  # Debian switched to systemd-timesyncd for ntp starting with bookworm
  if debian_version == 'buster' or debian_version == 'bullseye':
      fai_classes += ['TIME_CHRONY']
  else:
      fai_classes += ['TIME_SYSTEMD']
  # Arch-specific classes
  if platform.machine() == 'aarch64':
    fai_classes += ['ARM64', 'GRUB_EFI_ARM64']
  else:
    fai_classes += ['AMD64', 'GRUB_CLOUD_AMD64']
  # Version-specific classes used to select release and kernel
  if debian_version == 'buster':  # Debian 10
    fai_classes += ['BUSTER', 'LINUX_VERSION_BASE+LINUX_VARIANT_CLOUD']
  elif debian_version == 'bullseye':  # Debian 11
    fai_classes += ['BULLSEYE', 'LINUX_VERSION_BASE+LINUX_VARIANT_CLOUD']
    # Use the backports kernel for Bullseye arm64 due to gVNIC.
    if platform.machine() == 'aarch64':  # Debian 11 arm64
      fai_classes += ['LINUX_VERSION_BACKPORTS',
                      'LINUX_VERSION_BACKPORTS+LINUX_VARIANT_CLOUD']
  elif debian_version == 'bookworm':  # Debian 12
    fai_classes += ['BOOKWORM', 'LINUX_VERSION_BASE+LINUX_VARIANT_CLOUD']
  elif debian_version == 'sid':  # Debian unstable
    fai_classes += ['SID', 'LINUX_VERSION_BASE+LINUX_VARIANT_CLOUD']
  image_size = '10G'
  disk_name = 'disk.raw'
  # Run fai-tool.
  cmd = ['fai-diskimage', '--verbose', '--class',
         ','.join(fai_classes), '--size', image_size, '--cspace',
         config_space, disk_name]
  logging.info('Starting build in %s with params: %s', work_dir, ' '.join(cmd))
  returncode, output = utils.Execute(
      cmd, cwd=work_dir, capture_output=True, raise_errors=False)
  # Verbose printing to console for debugging.
  for line in output.splitlines():
    print(line)
  if returncode != 0:
    raise subprocess.CalledProcessError(returncode, cmd)
  # Packs a gzipped tar file with disk.raw inside
  disk_tar_gz = 'debian-{}-{}.tar.gz'.format(debian_version, build_date)
  logging.info('Compressing it into tarball %s', disk_tar_gz)
  tar = tarfile.open(disk_tar_gz, 'w:gz', format=tarfile.GNU_FORMAT)
  tar.add('%s/%s' % (work_dir, disk_name), arcname=disk_name)
  tar.close()
  # Upload tar.
  image_dest = os.path.join(outs_path, 'root.tar.gz')
  logging.info('Saving %s to %s', disk_tar_gz, image_dest)
  utils.UploadFile(disk_tar_gz, image_dest)