#!/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_create('-f', iotests.imgfmt, source_img_path, img_size)
    iotests.qemu_img_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')
        if event1['data']['status'] == 'postcopy-active':
            # This event is racy, it depends do we really do postcopy or bitmap
            # was migrated during downtime (and no data to migrate in postcopy
            # phase). So, don't log it.
            continue
        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]['inserted']['dirty-bitmaps'])

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