1import logging
2from autotest_lib.client.common_lib import error
3from autotest_lib.client.virt import virt_utils, virt_test_utils
4
5
6def run_mac_change(test, params, env):
7    """
8    Change MAC address of guest.
9
10    1) Get a new mac from pool, and the old mac addr of guest.
11    2) Set new mac in guest and regain new IP.
12    3) Re-log into guest with new MAC.
13
14    @param test: KVM test object.
15    @param params: Dictionary with the test parameters.
16    @param env: Dictionary with test environment.
17    """
18    vm = env.get_vm(params["main_vm"])
19    vm.verify_alive()
20    timeout = int(params.get("login_timeout", 360))
21    session_serial = vm.wait_for_serial_login(timeout=timeout)
22    # This session will be used to assess whether the IP change worked
23    session = vm.wait_for_login(timeout=timeout)
24    old_mac = vm.get_mac_address(0)
25    while True:
26        vm.free_mac_address(0)
27        new_mac = virt_utils.generate_mac_address(vm.instance, 0)
28        if old_mac != new_mac:
29            break
30    logging.info("The initial MAC address is %s", old_mac)
31    interface = virt_test_utils.get_linux_ifname(session_serial, old_mac)
32    # Start change MAC address
33    logging.info("Changing MAC address to %s", new_mac)
34    change_cmd = ("ifconfig %s down && ifconfig %s hw ether %s && "
35                  "ifconfig %s up" % (interface, interface, new_mac, interface))
36    session_serial.cmd(change_cmd)
37
38    # Verify whether MAC address was changed to the new one
39    logging.info("Verifying the new mac address")
40    session_serial.cmd("ifconfig | grep -i %s" % new_mac)
41
42    # Restart `dhclient' to regain IP for new mac address
43    logging.info("Restart the network to gain new IP")
44    dhclient_cmd = "dhclient -r && dhclient %s" % interface
45    session_serial.sendline(dhclient_cmd)
46
47    # Re-log into the guest after changing mac address
48    if virt_utils.wait_for(session.is_responsive, 120, 20, 3):
49        # Just warning when failed to see the session become dead,
50        # because there is a little chance the ip does not change.
51        logging.warning("The session is still responsive, settings may fail.")
52    session.close()
53
54    # Re-log into guest and check if session is responsive
55    logging.info("Re-log into the guest")
56    session = vm.wait_for_login(timeout=timeout)
57    if not session.is_responsive():
58        raise error.TestFail("The new session is not responsive.")
59
60    session.close()
61