• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2015 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""This module provides some utilities used by LXC and its tools.
6"""
7
8import common
9from autotest_lib.client.bin import utils
10from autotest_lib.client.common_lib import error
11from autotest_lib.client.common_lib.cros.network import interface
12
13
14def path_exists(path):
15    """Check if path exists.
16
17    If the process is not running with root user, os.path.exists may fail to
18    check if a path owned by root user exists. This function uses command
19    `test -e` to check if path exists.
20
21    @param path: Path to check if it exists.
22
23    @return: True if path exists, otherwise False.
24    """
25    try:
26        utils.run('sudo test -e "%s"' % path)
27        return True
28    except error.CmdError:
29        return False
30
31
32def get_host_ip():
33    """Get the IP address of the host running containers on lxcbr*.
34
35    This function gets the IP address on network interface lxcbr*. The
36    assumption is that lxc uses the network interface started with "lxcbr".
37
38    @return: IP address of the host running containers.
39    """
40    # The kernel publishes symlinks to various network devices in /sys.
41    result = utils.run('ls /sys/class/net', ignore_status=True)
42    # filter out empty strings
43    interface_names = [x for x in result.stdout.split() if x]
44
45    lxc_network = None
46    for name in interface_names:
47        if name.startswith('lxcbr'):
48            lxc_network = name
49            break
50    if not lxc_network:
51        raise error.ContainerError('Failed to find network interface used by '
52                                   'lxc. All existing interfaces are: %s' %
53                                   interface_names)
54    netif = interface.Interface(lxc_network)
55    return netif.ipv4_address
56
57def clone(lxc_path, src_name, new_path, dst_name, snapshot):
58    """Clones a container.
59
60    @param lxc_path: The LXC path of the source container.
61    @param src_name: The name of the source container.
62    @param new_path: The LXC path of the destination container.
63    @param dst_name: The name of the destination container.
64    @param snapshot: Whether or not to create a snapshot clone.
65    """
66    snapshot_arg = '-s' if snapshot else ''
67    # overlayfs is the default clone backend storage. However it is not
68    # supported in Ganeti yet. Use aufs as the alternative.
69    aufs_arg = '-B aufs' if utils.is_vm() and snapshot else ''
70    cmd = (('sudo lxc-clone --lxcpath {lxcpath} --newpath {newpath} '
71            '--orig {orig} --new {new} {snapshot} {backing}')
72           .format(
73               lxcpath = lxc_path,
74               newpath = new_path,
75               orig = src_name,
76               new = dst_name,
77               snapshot = snapshot_arg,
78               backing = aufs_arg
79           ))
80    utils.run(cmd)
81
82
83def cleanup_host_mount(host_dir):
84    """Unmounts and removes the given host dir.
85
86    @param host_dir: The host dir to unmount and remove.
87    """
88    try:
89        utils.run('sudo umount "%s"' % host_dir)
90    except error.CmdError:
91        # Ignore errors.  Most likely this occurred because the host dir
92        # was already unmounted.
93        pass
94    utils.run('sudo rm -r "%s"' % host_dir)
95