def setUp(self):
     super(RootFsRawTest, self).setUp()
     self._bundle = block_disk.RootFsRaw(10 * 1024 * 1024, 'ext4', False,
                                         self._MockStatvfs)
     self._tar_path = self.tmp_path + '/image.tar.gz'
     self._bundle.SetTarfile(self._tar_path)
     self._bundle.AppendExcludes([exclude_spec.ExcludeSpec(self._tar_path)])
     self._bundle._SetManifest(self._manifest)
Example #2
0
def main():
    parser = SetupArgsParser()
    (options, _) = parser.parse_args()
    if options.display_version:
        PrintVersionInfo()
        return 0
    EnsureSuperUser()
    VerifyArgs(parser, options)

    scratch_dir = tempfile.mkdtemp(dir=options.output_directory)
    SetupLogging(options, scratch_dir)
    logging.warn(
        '============================================================\n'
        'Warning: gcimagebundle is deprecated. See\n'
        'https://cloud.google.com/compute/docs/creating-custom-image'
        '#export_an_image_to_google_cloud_storage\n'
        'for updated instructions.\n'
        '============================================================')
    try:
        guest_platform = platform_factory.PlatformFactory(
            options.root_directory).GetPlatform()
    except platform_factory.UnknownPlatformException:
        logging.critical(
            'Platform is not supported.'
            ' Platform rules can be added to platform_factory.py.')
        return -1

    temp_file_name = tempfile.mktemp(dir=scratch_dir, suffix='.tar.gz')

    file_system = GetTargetFilesystem(options, guest_platform)
    logging.info('File System: %s', file_system)
    logging.info('Disk Size: %s bytes', options.fs_size)
    bundle = block_disk.RootFsRaw(options.fs_size, file_system,
                                  options.skip_disk_space_check)
    bundle.SetTarfile(temp_file_name)
    if options.disk:
        readlink_command = ['readlink', '-f', options.disk]
        final_path = utils.RunCommand(readlink_command).strip()
        logging.info('Resolved %s to %s', options.disk, final_path)
        bundle.AddDisk(final_path)
        # TODO(user): Find the location where the first partition of the disk
        # is mounted and add it as the source instead of relying on the source
        # param flag
    bundle.AddSource(options.root_directory)
    bundle.SetKey(options.key)
    bundle.SetScratchDirectory(scratch_dir)

    # Merge platform specific exclude list, mounts points
    # and user specified excludes
    excludes = guest_platform.GetExcludeList()
    if options.excludes:
        excludes.extend(
            [exclude_spec.ExcludeSpec(x) for x in options.excludes.split(',')])
    logging.info('exclude list: %s', ' '.join([x.GetSpec() for x in excludes]))
    bundle.AppendExcludes(excludes)
    if not options.include_mounts:
        mount_points = utils.GetMounts(options.root_directory)
        logging.info('ignoring mounts %s', ' '.join(mount_points))
        bundle.AppendExcludes([
            exclude_spec.ExcludeSpec(x, preserve_dir=True)
            for x in utils.GetMounts(options.root_directory)
        ])
    bundle.SetPlatform(guest_platform)

    # Verify that bundle attributes are correct and create tar bundle.
    bundle.Verify()
    (fs_size, digest) = bundle.Bundleup()
    if not digest:
        logging.critical('Could not get digest for the bundle.'
                         ' The bundle may not be created correctly')
        return -1
    if fs_size > options.fs_size:
        logging.critical('Size of tar %d exceeds the file system size %d.',
                         fs_size, options.fs_size)
        return -1

    if options.output_file_name:
        output_file = os.path.join(options.output_directory,
                                   options.output_file_name)
    else:
        output_file = os.path.join(options.output_directory,
                                   '%s.image.tar.gz' % digest)

    os.rename(temp_file_name, output_file)
    logging.info('Created tar.gz file at %s' % output_file)

    if options.bucket:
        bucket = options.bucket
        if bucket.startswith('gs://'):
            output_bucket = '%s/%s' % (bucket, os.path.basename(output_file))
        else:
            output_bucket = 'gs://%s/%s' % (bucket,
                                            os.path.basename(output_file))

        # /usr/local/bin not in redhat root PATH by default
        if '/usr/local/bin' not in os.environ['PATH']:
            os.environ['PATH'] += ':/usr/local/bin'

        # TODO: Consider using boto library directly.
        cmd = ['gsutil', 'cp', output_file, output_bucket]
        retcode = subprocess.call(cmd)
        if retcode != 0:
            logging.critical(
                'Failed to copy image to bucket. '
                'gsutil returned %d. To retry, run the command: %s', retcode,
                ' '.join(cmd))

            return -1
        logging.info('Uploaded image to %s', output_bucket)

        # If we've uploaded, then we can remove the local file.
        os.remove(output_file)

    if options.cleanup:
        shutil.rmtree(scratch_dir)