#!/usr/bin/env python3
# group: rw migration quick
#
# Copyright (C) 2017 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: Stefan Hajnoczi <stefanha@redhat.com>
#
# Non-shared storage migration test using NBD server and drive-mirror

import iotests

iotests.script_initialize(supported_fmts=['qcow2', 'qed', 'raw'],
                          supported_platforms=['linux'])

with iotests.FilePath('source.img') as source_img_path, \
     iotests.FilePath('dest.img') as dest_img_path, \
     iotests.FilePath('migration.sock', 'nbd.sock', base_dir=iotests.sock_dir) \
        as (migration_sock_path, nbd_sock_path), \
     iotests.VM('source') as source_vm, \
     iotests.VM('dest') as dest_vm:

    img_size = '1G'
    iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, source_img_path, img_size)
    iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, dest_img_path, img_size)

    iotests.log('Launching VMs...')
    (source_vm.add_drive(source_img_path)
              .launch())
    (dest_vm.add_drive(dest_img_path)
            .add_incoming('unix:{0}'.format(migration_sock_path))
            .launch())

    source_vm.qmp_log('block-dirty-bitmap-add', node='drive0', name='bitmap0')

    iotests.log('Launching NBD server on destination...')
    iotests.log(dest_vm.qmp('nbd-server-start', addr={'type': 'unix', 'data': {'path': nbd_sock_path}}))
    iotests.log(dest_vm.qmp('nbd-server-add', device='drive0', writable=True))

    iotests.log('Starting `drive-mirror` on source...')
    iotests.log(source_vm.qmp(
                  'drive-mirror',
                  device='drive0',
                  target='nbd+unix:///drive0?socket={0}'.format(nbd_sock_path),
                  sync='full',
                  format='raw', # always raw, the server handles the format
                  mode='existing',
                  job_id='mirror-job0'))

    iotests.log('Waiting for `drive-mirror` to complete...')
    iotests.log(source_vm.event_wait('BLOCK_JOB_READY'),
                filters=[iotests.filter_qmp_event])

    iotests.log('Starting migration...')
    capabilities = [{'capability': 'events', 'state': True},
                    {'capability': 'dirty-bitmaps', 'state': True}]
    source_vm.qmp('migrate-set-capabilities', capabilities=capabilities)
    dest_vm.qmp('migrate-set-capabilities', capabilities=capabilities)
    iotests.log(source_vm.qmp('migrate', uri='unix:{0}'.format(migration_sock_path)))

    source_vm.qmp_log('migrate-start-postcopy')

    while True:
        event1 = source_vm.event_wait('MIGRATION')
        iotests.log(event1, filters=[iotests.filter_qmp_event])
        if event1['data']['status'] in ('completed', 'failed'):
            iotests.log('Gracefully ending the `drive-mirror` job on source...')
            iotests.log(source_vm.qmp('block-job-cancel', device='mirror-job0'))
            break

    while True:
        event2 = source_vm.event_wait('BLOCK_JOB_COMPLETED')
        iotests.log(event2, filters=[iotests.filter_qmp_event])
        if event2['event'] == 'BLOCK_JOB_COMPLETED':
            iotests.log('Stopping the NBD server on destination...')
            iotests.log(dest_vm.qmp('nbd-server-stop'))
            break

    iotests.log('Wait for migration completion on target...')
    migr_events = (('MIGRATION', {'data': {'status': 'completed'}}),
                   ('MIGRATION', {'data': {'status': 'failed'}}))
    event = dest_vm.events_wait(migr_events)
    iotests.log(event, filters=[iotests.filter_qmp_event])

    iotests.log('Check bitmaps on source:')
    iotests.log(source_vm.qmp('query-block')['return'][0]['dirty-bitmaps'])

    iotests.log('Check bitmaps on target:')
    iotests.log(dest_vm.qmp('query-block')['return'][0]['dirty-bitmaps'])
