#!/usr/bin/env python3
#
# Test for when a backing file is considered overridden (thus, a
# json:{} filename is generated for the overlay) and when it is not
#
# Copyright (C) 2018 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Creator/Owner: Max Reitz <mreitz@redhat.com>

import iotests
from iotests import log, qemu_img, filter_testfiles, filter_imgfmt, \
        filter_qmp_testfiles, filter_qmp_imgfmt

# Need backing file and change-backing-file support
iotests.verify_image_format(supported_fmts=['qcow2', 'qed'])
iotests.verify_platform(['linux'])


def log_node_info(node):
    log('')

    log('bs->filename: ' + node['image']['filename'],
        filters=[filter_testfiles, filter_imgfmt])
    log('bs->backing_file: ' + node['backing_file'],
        filters=[filter_testfiles, filter_imgfmt])

    if 'backing-image' in node['image']:
        log('bs->backing->bs->filename: ' +
            node['image']['backing-image']['filename'],
            filters=[filter_testfiles, filter_imgfmt])
    else:
        log('bs->backing: (none)')

    log('')


with iotests.FilePath('base.img') as base_img_path, \
     iotests.FilePath('top.img') as top_img_path, \
     iotests.VM() as vm:

    assert qemu_img('create', '-f', iotests.imgfmt, base_img_path, '64M') == 0
    # Choose a funny way to describe the backing filename
    assert qemu_img('create', '-f', iotests.imgfmt, '-b',
                    'file:' + base_img_path, top_img_path) == 0

    vm.launch()

    log('--- Implicit backing file ---')
    log('')

    vm.qmp_log('blockdev-add',
                node_name='node0',
                driver=iotests.imgfmt,
                file={
                    'driver': 'file',
                    'filename': top_img_path
                },
                filters=[filter_qmp_testfiles, filter_qmp_imgfmt])

    # Filename should be plain, and the backing filename should not
    # contain the "file:" prefix
    log_node_info(vm.node_info('node0'))

    vm.qmp_log('blockdev-del', node_name='node0')

    log('')
    log('--- change-backing-file ---')
    log('')

    vm.qmp_log('blockdev-add',
               node_name='node0',
               driver=iotests.imgfmt,
               file={
                   'driver': 'file',
                   'filename': top_img_path
               },
               filters=[filter_qmp_testfiles, filter_qmp_imgfmt])

    # Changing the backing file to a qemu-reported filename should
    # result in qemu accepting the corresponding BDS as the implicit
    # backing BDS (and thus not generate a json:{} filename).
    # So, first, query the backing filename.

    backing_filename = \
        vm.node_info('node0')['image']['backing-image']['filename']

    # Next, change the backing file to something different

    vm.qmp_log('change-backing-file',
               image_node_name='node0',
               device='node0',
               backing_file='null-co://',
               filters=[filter_qmp_testfiles])

    # Now, verify that we get a json:{} filename
    # (Image header says "null-co://", actual backing file still is
    # base_img_path)

    log_node_info(vm.node_info('node0'))

    # Change it back
    # (To get header and backing file in sync)

    vm.qmp_log('change-backing-file',
               image_node_name='node0',
               device='node0',
               backing_file=backing_filename,
               filters=[filter_qmp_testfiles])

    # And verify that we get our original results

    log_node_info(vm.node_info('node0'))

    # Finally, try a "file:" prefix.  While this is actually what we
    # originally had in the image header, qemu will not reopen the
    # backing file here, so it cannot verify that this filename
    # "resolves" to the actual backing BDS's filename and will thus
    # consider both to be different.
    # (This may be fixed in the future.)

    vm.qmp_log('change-backing-file',
               image_node_name='node0',
               device='node0',
               backing_file=('file:' + backing_filename),
               filters=[filter_qmp_testfiles])

    # So now we should get a json:{} filename

    log_node_info(vm.node_info('node0'))

    # Remove and re-attach so we can see that (as in our first try),
    # opening the image anew helps qemu resolve the header backing
    # filename.

    vm.qmp_log('blockdev-del', node_name='node0')

    vm.qmp_log('blockdev-add',
               node_name='node0',
               driver=iotests.imgfmt,
               file={
                   'driver': 'file',
                   'filename': top_img_path
               },
               filters=[filter_qmp_testfiles, filter_qmp_imgfmt])

    log_node_info(vm.node_info('node0'))

    vm.qmp_log('blockdev-del', node_name='node0')

    log('')
    log('--- Override backing file ---')
    log('')

    # For this test, we need the plain filename in the image header
    # (because qemu cannot "canonicalize"/"resolve" the backing
    # filename unless the backing file is opened implicitly with the
    # overlay)
    assert qemu_img('create', '-f', iotests.imgfmt, '-b', base_img_path,
                    top_img_path) == 0

    # You can only reliably override backing options by using a node
    # reference (or by specifying file.filename, but, well...)
    vm.qmp_log('blockdev-add', node_name='null', driver='null-co')

    vm.qmp_log('blockdev-add',
               node_name='node0',
               driver=iotests.imgfmt,
               file={
                   'driver': 'file',
                   'filename': top_img_path
               },
               backing='null',
               filters=[filter_qmp_testfiles, filter_qmp_imgfmt])

    # Should get a json:{} filename (and bs->backing_file is
    # null-co://, because that field actually has not much to do
    # with the header backing filename (except that it is changed by
    # change-backing-file))

    log_node_info(vm.node_info('node0'))

    # Detach the backing file by reopening the whole thing

    vm.qmp_log('blockdev-del', node_name='node0')
    vm.qmp_log('blockdev-del', node_name='null')

    vm.qmp_log('blockdev-add',
               node_name='node0',
               driver=iotests.imgfmt,
               file={
                   'driver': 'file',
                   'filename': top_img_path
               },
               backing=None,
               filters=[filter_qmp_testfiles, filter_qmp_imgfmt])

    # Should get a json:{} filename (because we overrode the backing
    # file to not be there)

    log_node_info(vm.node_info('node0'))

    # Open the original backing file

    vm.qmp_log('blockdev-add',
               node_name='original-backing',
               driver=iotests.imgfmt,
               file={
                   'driver': 'file',
                   'filename': base_img_path
               },
               filters=[filter_qmp_testfiles, filter_qmp_imgfmt])

    # Attach the original backing file to its overlay

    vm.qmp_log('blockdev-snapshot',
               node='original-backing',
               overlay='node0')

    # This should give us the original plain result

    log_node_info(vm.node_info('node0'))

    vm.qmp_log('blockdev-del', node_name='node0')
    vm.qmp_log('blockdev-del', node_name='original-backing')

    vm.shutdown()
