#!/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.script_initialize(
    supported_fmts=['qcow2', 'qed'],
    supported_platforms=['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()
