Пример #1
0
def test_snapshot_rm(
        bin,
        grpc_controller_client,  # NOQA
        grpc_replica_client,
        grpc_replica_client2):  # NOQA
    open_replica(grpc_replica_client)
    open_replica(grpc_replica_client2)

    r1_url = grpc_replica_client.url
    r2_url = grpc_replica_client2.url
    v = grpc_controller_client.volume_start(replicas=[
        r1_url,
        r2_url,
    ])
    assert v.replicaCount == 2

    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'create']
    subprocess.check_call(cmd)
    output = subprocess.check_output(cmd).strip()

    chain = grpc_replica_client.replica_get().chain
    assert len(chain) == 3
    assert chain[0] == 'volume-head-002.img'
    assert chain[1] == 'volume-snap-{}.img'.format(output)

    cmd = [
        bin, '--url', grpc_controller_client.address, 'snapshot', 'rm', output
    ]
    subprocess.check_call(cmd)

    new_chain = grpc_replica_client.replica_get().chain
    assert len(new_chain) == 2
    assert chain[0] == new_chain[0]
    assert chain[2] == new_chain[1]
Пример #2
0
def test_snapshot_purge_basic(
        bin,
        grpc_controller_client,  # NOQA
        grpc_replica_client,  # NOQA
        grpc_replica_client2):  # NOQA
    open_replica(grpc_replica_client)
    open_replica(grpc_replica_client2)

    r1_url = grpc_replica_client.url
    r2_url = grpc_replica_client2.url
    v = grpc_controller_client.volume_start(replicas=[
        r1_url,
        r2_url,
    ])
    assert v.replicaCount == 2

    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'create']
    snap0 = subprocess.check_output(cmd).strip()
    snap1 = subprocess.check_output(cmd).strip()

    chain = grpc_replica_client.replica_get().chain
    assert len(chain) == 3
    assert chain[0] == 'volume-head-002.img'
    assert chain[1] == 'volume-snap-{}.img'.format(snap1)
    assert chain[2] == 'volume-snap-{}.img'.format(snap0)

    cmd = [
        bin, '--url', grpc_controller_client.address, 'snapshot', 'rm', snap0
    ]
    subprocess.check_call(cmd)

    new_chain = grpc_replica_client.replica_get().chain
    assert len(new_chain) == 2
    assert chain[0] == new_chain[0]
    assert chain[1] == new_chain[1]

    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'info']
    output = subprocess.check_output(cmd)
    info = json.loads(output)

    assert len(info) == 3
    assert info[snap0]["parent"] == ""
    assert info[snap0]["removed"] is True
    assert info[snap1]["parent"] == snap0
    assert info[snap1]["removed"] is False
    assert info[VOLUME_HEAD]["parent"] == snap1

    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'purge']
    subprocess.check_call(cmd)

    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'info']
    output = subprocess.check_output(cmd)
    info = json.loads(output)

    assert len(info) == 2
    assert snap0 not in info
    assert info[snap1]["parent"] == ""
Пример #3
0
def test_open(grpc_client):  # NOQA
    r = grpc_client.replica_get()
    assert r.state == 'initial'
    assert r.size == '0'
    assert r.sectorSize == 0
    assert r.parent == ''
    assert r.head == ''

    r = grpc_client.replica_create(size=SIZE_STR)

    assert r.state == 'closed'
    assert not r.dirty
    assert not r.rebuilding
    assert r.size == SIZE_STR
    assert r.sectorSize == 512
    assert r.parent == ''
    assert r.head == 'volume-head-000.img'

    r = grpc_client.replica_open()

    assert r.state == 'open'
    assert not r.dirty
    assert not r.rebuilding
    assert r.size == SIZE_STR
    assert r.sectorSize == 512
    assert r.parent == ''
    assert r.head == 'volume-head-000.img'
Пример #4
0
def test_snapshot_rm_empty(
        bin,
        grpc_controller_client,  # NOQA
        grpc_replica_client,  # NOQA
        grpc_replica_client2):  # NOQA
    open_replica(grpc_replica_client)
    open_replica(grpc_replica_client2)

    r1_url = grpc_replica_client.url
    r2_url = grpc_replica_client2.url
    v = grpc_controller_client.volume_start(replicas=[
        r1_url,
        r2_url,
    ])
    assert v.replicaCount == 2

    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'create']

    # first snapshot
    output1 = subprocess.check_output(cmd).strip()
    chain = grpc_replica_client.replica_get().chain
    assert len(chain) == 2
    assert chain[0] == 'volume-head-001.img'
    assert chain[1] == 'volume-snap-{}.img'.format(output1)

    # second snapshot
    output2 = subprocess.check_output(cmd).strip()
    chain = grpc_replica_client.replica_get().chain
    assert len(chain) == 3
    assert chain[0] == 'volume-head-002.img'
    assert chain[1] == 'volume-snap-{}.img'.format(output2)
    assert chain[2] == 'volume-snap-{}.img'.format(output1)

    # remove the first snapshot(empty), it will fold second snapshot(empty)
    # to the first snapshot(empty) and rename it to second snapshot
    cmd = [
        bin, '--url', grpc_controller_client.address, 'snapshot', 'rm', output1
    ]
    subprocess.check_call(cmd)
    new_chain = grpc_replica_client.replica_get().chain
    assert len(new_chain) == 2
    assert chain[0] == new_chain[0]
    assert chain[1] == new_chain[1]
Пример #5
0
def test_snapshot_create(
        bin,
        grpc_controller_client,  # NOQA
        grpc_replica_client,  # NOQA
        grpc_replica_client2):  # NOQA
    open_replica(grpc_replica_client)
    open_replica(grpc_replica_client2)

    r1_url = grpc_replica_client.url
    r2_url = grpc_replica_client2.url
    v = grpc_controller_client.volume_start(replicas=[
        r1_url,
        r2_url,
    ])
    assert v.replicaCount == 2

    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'create']
    snap0 = subprocess.check_output(cmd).strip()
    expected = grpc_replica_client.replica_get().chain[1]
    assert expected == 'volume-snap-{}.img'.format(snap0)

    cmd = [
        bin, '--url', grpc_controller_client.address, 'snapshot', 'create',
        '--label', 'name=snap1', '--label', 'key=value'
    ]
    snap1 = subprocess.check_output(cmd).strip()

    cmd = [
        bin, '--debug', '--url', grpc_controller_client.address, 'snapshot',
        'ls'
    ]
    ls_output = subprocess.check_output(cmd)

    assert ls_output == '''ID
{}
{}
'''.format(snap1, snap0)

    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'info']
    output = subprocess.check_output(cmd)
    info = json.loads(output)

    assert len(info) == 3
    assert info[snap0]["parent"] == ""
    assert info[snap0]["removed"] is False
    assert len(info[snap0]["labels"]) == 0
    assert info[snap1]["parent"] == snap0
    assert info[snap1]["removed"] is False
    assert len(info[snap1]["labels"]) == 2
    assert info[snap1]["labels"]["name"] == "snap1"
    assert info[snap1]["labels"]["key"] == "value"
    assert info[VOLUME_HEAD]["parent"] == snap1
    assert len(info[VOLUME_HEAD]["labels"]) == 0
Пример #6
0
def test_revert(
        engine_manager_client,  # NOQA
        grpc_controller_client,  # NOQA
        grpc_replica_client,  # NOQA
        grpc_replica_client2):  # NOQA
    open_replica(grpc_replica_client)
    open_replica(grpc_replica_client2)

    r1_url = grpc_replica_client.url
    r2_url = grpc_replica_client2.url
    v = grpc_controller_client.volume_start(replicas=[
        r1_url,
        r2_url,
    ])
    assert v.replicaCount == 2

    snap = grpc_controller_client.volume_snapshot(name='foo1')
    assert snap == 'foo1'

    snap2 = grpc_controller_client.volume_snapshot(name='foo2')
    assert snap2 == 'foo2'

    r1 = grpc_replica_client.replica_get()
    r2 = grpc_replica_client2.replica_get()

    assert r1.chain == [
        'volume-head-002.img', 'volume-snap-foo2.img', 'volume-snap-foo1.img'
    ]
    assert r1.chain == r2.chain

    engine_manager_client.frontend_shutdown(ENGINE_NAME)
    grpc_controller_client.volume_revert(name='foo1')
    engine_manager_client.frontend_start(ENGINE_NAME, FRONTEND_TGT_BLOCKDEV)
    r1 = grpc_replica_client.replica_get()
    r2 = grpc_replica_client2.replica_get()
    assert r1.chain == ['volume-head-003.img', 'volume-snap-foo1.img']
    assert r1.chain == r2.chain
Пример #7
0
def test_reload(grpc_client):  # NOQA
    grpc_client.replica_create(size=SIZE_STR)
    grpc_client.replica_open()

    r = grpc_client.replica_get()
    assert r.chain == ['volume-head-000.img']

    r = grpc_client.replica_snapshot(
        name='000', created=datetime.datetime.utcnow().isoformat())
    assert r.chain == ['volume-head-001.img', 'volume-snap-000.img']
    r = grpc_client.replica_snapshot(
        name='001', created=datetime.datetime.utcnow().isoformat())
    assert r.chain == [
        'volume-head-002.img', 'volume-snap-001.img', 'volume-snap-000.img'
    ]

    r = grpc_client.disk_remove(name='volume-snap-000.img')
    assert r.state == 'dirty'
    assert r.size == SIZE_STR
    assert r.sectorSize == 512
    assert r.head == 'volume-head-002.img'
    assert r.parent == 'volume-snap-001.img'
    assert r.chain == ['volume-head-002.img', 'volume-snap-001.img']

    r = grpc_client.replica_reload()
    assert r.state == 'dirty'
    assert r.size == SIZE_STR
    assert r.sectorSize == 512
    assert r.chain == ['volume-head-002.img', 'volume-snap-001.img']
    assert r.head == 'volume-head-002.img'
    assert r.parent == 'volume-snap-001.img'

    grpc_client.replica_close()
    r = grpc_client.replica_open()
    assert r.state == 'open'
    assert r.size == SIZE_STR
    assert r.sectorSize == 512
    assert r.chain == ['volume-head-002.img', 'volume-snap-001.img']
    assert r.head == 'volume-head-002.img'
    assert r.parent == 'volume-snap-001.img'
Пример #8
0
def test_snapshot_last(
        bin,
        grpc_controller_client,  # NOQA
        grpc_replica_client,  # NOQA
        grpc_replica_client2):  # NOQA
    open_replica(grpc_replica_client)
    open_replica(grpc_replica_client2)

    r1_url = grpc_replica_client.url
    r2_url = grpc_replica_client2.url
    v = grpc_controller_client.volume_start(replicas=[
        r1_url,
    ])
    assert v.replicaCount == 1

    cmd = [bin, '--url', grpc_controller_client.address, 'add', r2_url]
    subprocess.check_output(cmd)
    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'ls']
    output = subprocess.check_output(cmd)
    output = output.splitlines()[1]

    chain = grpc_replica_client.replica_get().chain
    assert len(chain) == 2
    assert chain[0] == 'volume-head-001.img'
    assert chain[1] == 'volume-snap-{}.img'.format(output)

    chain = grpc_replica_client2.replica_get().chain
    assert len(chain) == 2
    assert chain[0] == 'volume-head-001.img'
    assert chain[1] == 'volume-snap-{}.img'.format(output)

    # it will be marked as removed
    cmd = [
        bin, '--url', grpc_controller_client.address, 'snapshot', 'rm', output
    ]
    subprocess.check_call(cmd)
Пример #9
0
def backup_core(
        bin,
        engine_manager_client,  # NOQA
        grpc_controller_client,  # NOQA
        grpc_replica_client,  # NOQA
        grpc_replica_client2,  # NOQA
        backup_target):
    open_replica(grpc_replica_client)
    open_replica(grpc_replica_client2)

    r1_url = grpc_replica_client.url
    r2_url = grpc_replica_client2.url
    v = grpc_controller_client.volume_start(replicas=[
        r1_url,
        r2_url,
    ])
    assert v.replicaCount == 2

    env = dict(os.environ)
    backup_type = urlparse(backup_target).scheme
    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'create']
    snapshot1 = subprocess.check_output(cmd).strip()
    output = grpc_replica_client.replica_get().chain[1]

    assert output == 'volume-snap-{}.img'.format(snapshot1)

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'create',
        snapshot1, '--dest', backup_target, '--label', 'name=backup1',
        '--label', 'type=' + backup_type
    ]
    backup = json.loads(subprocess.check_output(cmd, env=env).strip())
    assert "backupID" in backup.keys()
    assert "isIncremental" in backup.keys()
    assert backup["isIncremental"] is False
    backup1 = get_backup_url(bin, grpc_controller_client.address,
                             backup["backupID"])

    cmd = [bin, '--url', grpc_controller_client.address, 'snapshot', 'create']
    snapshot2 = subprocess.check_output(cmd).strip()
    output = grpc_replica_client.replica_get().chain[1]

    assert output == 'volume-snap-{}.img'.format(snapshot2)

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'create',
        snapshot2, '--dest', backup_target
    ]
    backup = json.loads(subprocess.check_output(cmd, env=env).strip())
    assert "backupID" in backup.keys()
    assert "isIncremental" in backup.keys()
    assert backup["isIncremental"] is True
    backup2 = get_backup_url(bin, grpc_controller_client.address,
                             backup["backupID"])

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'inspect',
        backup1
    ]
    data = subprocess.check_output(cmd, env=env)
    backup1_info = json.loads(data)
    assert backup1_info["URL"] == backup1
    assert backup1_info["VolumeName"] == VOLUME_NAME
    assert backup1_info["VolumeSize"] == SIZE_STR
    assert backup1_info["SnapshotName"] == snapshot1
    assert len(backup1_info["Labels"]) == 2
    assert backup1_info["Labels"]["name"] == "backup1"
    assert backup1_info["Labels"]["type"] == backup_type

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'inspect',
        backup2
    ]
    data = subprocess.check_output(cmd, env=env)
    backup2_info = json.loads(data)
    assert backup2_info["URL"] == backup2
    assert backup2_info["VolumeName"] == VOLUME_NAME
    assert backup2_info["VolumeSize"] == SIZE_STR
    assert backup2_info["SnapshotName"] == snapshot2
    if backup2_info["Labels"] is not None:
        assert len(backup2_info["Labels"]) == 0

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'ls',
        backup_target
    ]
    data = subprocess.check_output(cmd, env=env).strip()
    volume_info = json.loads(data)[VOLUME_NAME]
    assert volume_info["Name"] == VOLUME_NAME
    assert volume_info["Size"] == SIZE_STR
    backup_list = volume_info["Backups"]
    assert backup_list[backup1]["URL"] == backup1_info["URL"]
    assert backup_list[backup1]["SnapshotName"] == backup1_info["SnapshotName"]
    assert backup_list[backup1]["Size"] == backup1_info["Size"]
    assert backup_list[backup1]["Created"] == backup1_info["Created"]
    assert backup_list[backup2]["URL"] == backup2_info["URL"]
    assert backup_list[backup2]["SnapshotName"] == backup2_info["SnapshotName"]
    assert backup_list[backup2]["Size"] == backup2_info["Size"]
    assert backup_list[backup2]["Created"] == backup2_info["Created"]

    # test backup volume list
    # https://github.com/rancher/longhorn/issues/399
    volume_dir = finddir(BACKUP_DEST, VOLUME_NAME)
    assert volume_dir
    assert path.exists(volume_dir)
    volume_cfg_path = findfile(volume_dir, VOLUME_CONFIG_FILE)
    assert path.exists(volume_cfg_path)
    volume_tmp_cfg_path = volume_cfg_path.replace(VOLUME_CONFIG_FILE,
                                                  VOLUME_TMP_CONFIG_FILE)
    os.rename(volume_cfg_path, volume_tmp_cfg_path)
    assert path.exists(volume_tmp_cfg_path)

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'ls',
        '--volume-only', backup_target
    ]
    data = subprocess.check_output(cmd, env=env)
    volume_info = json.loads(data)

    assert volume_info
    assert volume_info[VOLUME_NAME] is not None
    assert volume_info[VOLUME_NAME]["Messages"] is not None
    assert MESSAGE_TYPE_ERROR in volume_info[VOLUME_NAME]["Messages"]

    os.rename(volume_tmp_cfg_path, volume_cfg_path)
    assert path.exists(volume_cfg_path)

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'ls',
        '--volume-only', backup_target
    ]
    data = subprocess.check_output(cmd, env=env)
    volume_info = json.loads(data)

    assert volume_info
    assert volume_info[VOLUME_NAME] is not None
    assert volume_info[VOLUME_NAME]["Messages"] is not None
    assert MESSAGE_TYPE_ERROR not in volume_info[VOLUME_NAME]["Messages"]

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'inspect',
        backup_target + "?backup=backup-1234" + "&volume=" + VOLUME_NAME
    ]
    # cannot find the backup
    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call(cmd, env=env)

    restore_backup(engine_manager_client, bin, grpc_controller_client.address,
                   backup1, env, grpc_controller_client)
    restore_backup(engine_manager_client, bin, grpc_controller_client.address,
                   backup2, env, grpc_controller_client)

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'rm', backup1
    ]
    subprocess.check_call(cmd, env=env)
    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'rm', backup2
    ]
    subprocess.check_call(cmd, env=env)

    assert os.path.exists(BACKUP_DEST)

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'inspect',
        backup_target + "?backup=backup-1234" + "&volume=" + VOLUME_NAME
    ]
    # cannot find the backup
    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call(cmd, env=env)

    cmd = [
        bin, '--url', grpc_controller_client.address, 'backup', 'inspect',
        "xxx"
    ]
    # cannot find the backup
    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call(cmd, env=env)
    engine_manager_client.frontend_start(ENGINE_NAME, FRONTEND_TGT_BLOCKDEV)
    v = grpc_controller_client.volume_get()
    assert v.frontendState == "up"