# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Support for Linux namespaces"""

from __future__ import print_function

import ctypes
import ctypes.util
import errno
import os
# Note: We avoid cros_build_lib here as that's a "large" module and we want
# to keep this "light" and standalone.  The subprocess usage in here is also
# simple by design -- if it gets more complicated, we should look at using
# the RunCommand helper.
import subprocess
import sys

from chromite.lib import osutils
from chromite.lib import process_util


CLONE_FS = 0x00000200
CLONE_FILES = 0x00000400
CLONE_NEWNS = 0x00020000
CLONE_NEWUTS = 0x04000000
CLONE_NEWIPC = 0x08000000
CLONE_NEWUSER = 0x10000000
CLONE_NEWPID = 0x20000000
CLONE_NEWNET = 0x40000000


def SetNS(fd, nstype):
  """Binding to the Linux setns system call. See setns(2) for details.

  Args:
    fd: An open file descriptor or path to one.
    nstype: Namespace to enter; one of CLONE_*.

  Raises:
    OSError: if setns failed.
  """
  try:
    fp = None
    if isinstance(fd, basestring):
      fp = open(fd)
      fd = fp.fileno()

    libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
    if libc.setns(ctypes.c_int(fd), ctypes.c_int(nstype)) != 0:
      e = ctypes.get_errno()
      raise OSError(e, os.strerror(e))
  finally:
    if fp is not None:
      fp.close()


def Unshare(flags):
  """Binding to the Linux unshare system call. See unshare(2) for details.

  Args:
    flags: Namespaces to unshare; bitwise OR of CLONE_* flags.

  Raises:
    OSError: if unshare failed.
  """
  libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
  if libc.unshare(ctypes.c_int(flags)) != 0:
    e = ctypes.get_errno()
    raise OSError(e, os.strerror(e))


def _ReapChildren(pid):
  """Reap all children that get reparented to us until we see |pid| exit.

  Args:
    pid: The main child to watch for.

  Returns:
    The wait status of the |pid| child.
  """
  pid_status = 0

  while True:
    try:
      (wpid, status) = os.wait()
      if pid == wpid:
        # Save the status of our main child so we can exit with it below.
        pid_status = status
    except OSError as e:
      if e.errno == errno.ECHILD:
        break
      else:
        raise

  return pid_status


def CreatePidNs():
  """Start a new pid namespace

  This will launch all the right manager processes.  The child that returns
  will be isolated in a new pid namespace.

  If functionality is not available, then it will return w/out doing anything.

  Returns:
    The last pid outside of the namespace.
  """
  first_pid = os.getpid()

  try:
    # First create the namespace.
    Unshare(CLONE_NEWPID)
  except OSError as e:
    if e.errno == errno.EINVAL:
      # For older kernels, or the functionality is disabled in the config,
      # return silently.  We don't want to hard require this stuff.
      return first_pid
    else:
      # For all other errors, abort.  They shouldn't happen.
      raise

  # Now that we're in the new pid namespace, fork.  The parent is the master
  # of it in the original namespace, so it only monitors the child inside it.
  # It is only allowed to fork once too.
  pid = os.fork()
  if pid:
    # Reap the children as the parent of the new namespace.
    process_util.ExitAsStatus(_ReapChildren(pid))
  else:
    # Make sure to unshare the existing mount point if needed.  Some distros
    # create shared mount points everywhere by default.
    try:
      osutils.Mount('none', '/proc', 0, osutils.MS_PRIVATE | osutils.MS_REC)
    except OSError as e:
      if e.errno != errno.EINVAL:
        raise

    # The child needs its own proc mount as it'll be different.
    osutils.Mount('proc', '/proc', 'proc',
                  osutils.MS_NOSUID | osutils.MS_NODEV | osutils.MS_NOEXEC |
                  osutils.MS_RELATIME)

    pid = os.fork()
    if pid:
      # Watch all of the children.  We need to act as the master inside the
      # namespace and reap old processes.
      process_util.ExitAsStatus(_ReapChildren(pid))

  # The grandchild will return and take over the rest of the sdk steps.
  return first_pid


def CreateNetNs():
  """Start a new net namespace

  We will bring up the loopback interface, but that is all.

  If functionality is not available, then it will return w/out doing anything.
  """
  # The net namespace was added in 2.6.24 and may be disabled in the kernel.
  try:
    Unshare(CLONE_NEWNET)
  except OSError as e:
    if e.errno == errno.EINVAL:
      return
    else:
      # For all other errors, abort.  They shouldn't happen.
      raise

  # Since we've unshared the net namespace, we need to bring up loopback.
  # The kernel automatically adds the various ip addresses, so skip that.
  try:
    subprocess.call(['ip', 'link', 'set', 'up', 'lo'])
  except OSError as e:
    if e.errno == errno.ENOENT:
      print('warning: could not bring up loopback for network; '
            'install the iproute2 package', file=sys.stderr)
    else:
      raise


def SimpleUnshare(mount=True, uts=True, ipc=True, net=False, pid=False):
  """Simpler helper for setting up namespaces quickly.

  If support for any namespace type is not available, we'll silently skip it.

  Args:
    mount: Create a mount namespace.
    uts: Create a UTS namespace.
    ipc: Create an IPC namespace.
    net: Create a net namespace.
    pid: Create a pid namespace.
  """
  # The mount namespace is the only one really guaranteed to exist --
  # it's been supported forever and it cannot be turned off.
  if mount:
    Unshare(CLONE_NEWNS)

  # The UTS namespace was added 2.6.19 and may be disabled in the kernel.
  if uts:
    try:
      Unshare(CLONE_NEWUTS)
    except OSError as e:
      if e.errno != errno.EINVAL:
        pass

  # The IPC namespace was added 2.6.19 and may be disabled in the kernel.
  if ipc:
    try:
      Unshare(CLONE_NEWIPC)
    except OSError as e:
      if e.errno != errno.EINVAL:
        pass

  if net:
    CreateNetNs()

  if pid:
    CreatePidNs()
