def test(self):
        """Test debmarshal.privops.call."""
        self.mox.StubOutWithMock(dbus, 'SystemBus', use_mock_anything=True)
        bus = self.mox.CreateMock(dbus.bus.BusConnection)
        proxy = self.mox.CreateMockAnything()
        method = self.mox.CreateMockAnything()

        dbus.SystemBus().AndReturn(bus)
        bus.get_object(privops.DBUS_BUS_NAME,
                       privops.DBUS_OBJECT_PATH).AndReturn(proxy)
        proxy.get_dbus_method(
            'createNetwork',
            dbus_interface=privops.DBUS_INTERFACE).AndReturn(method)
        method(['www.company.com', 'login.company.com'])

        self.mox.ReplayAll()

        privops.call('createNetwork', ['www.company.com', 'login.company.com'])
Example #2
0
  def test(self):
    """Test debmarshal.privops.call."""
    self.mox.StubOutWithMock(dbus, 'SystemBus', use_mock_anything=True)
    bus = self.mox.CreateMock(dbus.bus.BusConnection)
    proxy = self.mox.CreateMockAnything()
    method = self.mox.CreateMockAnything()

    dbus.SystemBus().AndReturn(bus)
    bus.get_object(privops.DBUS_BUS_NAME, privops.DBUS_OBJECT_PATH).AndReturn(
      proxy)
    proxy.get_dbus_method(
        'createNetwork', dbus_interface=privops.DBUS_INTERFACE).AndReturn(
        method)
    method(['www.company.com', 'login.company.com'])

    self.mox.ReplayAll()

    privops.call('createNetwork', ['www.company.com', 'login.company.com'])
Example #3
0
def runTest(test):
  """Actually run a debmarshal test.

  Args:
    Path to the test to run.
  """
  start = time.time()

  # First, load the configuration
  config = yaml.safe_load(open(os.path.join(test, 'config.yml')))

  # Next, network configuration. Configure the network as it will be
  # for the test run.
  vms = config['vms'].keys()
  net_name, net_gate, net_mask, net_vms = privops.call('createNetwork',
                                                       vms)

  try:
    # Then, spawn the web server for serving the test configuration.
    httpd = subprocess.Popen(['python', '-m', 'debmarshal.web', test],
                             stdout=subprocess.PIPE)
    web_port = httpd.stdout.read()

    domain = config['domain']

    try:
      images = {}
      domains = {}

      for vm in vms:
        vm_config = config['vms'][vm]
        dist = base.findDistribution(vm_config['distribution'])
        pristine_disk_path = dist.diskPath(vm, domain, test, vm_config)

        fd, disk_path = tempfile.mkstemp()
        os.close(fd)
        subprocess.check_call(['cp',
                               '--sparse=always',
                               pristine_disk_path,
                               disk_path],
                              stdin=subprocess.PIPE,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE)
        images[vm] = disk_path

      for vm in vms:
        vm_config = config['vms'][vm]
        memory = vm_config.get('memory', '128M')
        arch = vm_config.get('arch', '')

        domains[vm] = privops.call('createDomain',
                                   memory,
                                   [images[vm]],
                                   net_name,
                                   net_vms[vm][1],
                                   'qemu',
                                   arch,
                                   {})

      # Wait for the master VM to boot up, then run the test
      key_path = os.path.join(test, 'id_rsa')
      master = vms[0]
      master_ip = net_vms[master][0]
      while True:
        if not subprocess.call(['ssh',
                                '-i', key_path,
                                '-o', 'ConnectTimeout=1',
                                '-l', 'root',
                                master_ip,
                                'true'],
                               stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE):
          break
        else:
          time.sleep(5)

      subprocess.check_call(['ssh',
                             '-i', key_path,
                             '-l', 'root',
                             master_ip,
                             'wget',
                             '-N',
                             '-O', '/root/script',
                             'http://%s:%s/script' % (net_gate, web_port)],
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
      ret = subprocess.call(['ssh',
                             '-i', key_path,
                             '-l', 'root',
                             master_ip,
                             '/root/script',
                             str(web_port)],
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
      print ret

    finally:
      for domain in domains.values():
        privops.call('destroyDomain', domain, 'qemu')

      for image in images.values():
        os.unlink(image)

      os.kill(httpd.pid, signal.SIGTERM)
  finally:
    privops.call('destroyNetwork', net_name)
Example #4
0
def prepareTest(test):
  """Prepare the disk image for a single test.

  Args:
    Path to a debmarshal test.
  """
  start = time.time()

  # First, load the configuration
  config = yaml.safe_load(open(os.path.join(test, 'config.yml')))

  # Next, network configuration. Configure the network as it will be
  # for the test run.
  vms = config['vms'].keys()
  net_name, net_gate, net_mask, net_vms = privops.call('createNetwork',
                                                       vms)

  # If there's not already an ssh key packaged with the test to use,
  # generate one.
  key_path = os.path.join(test, 'id_rsa')
  if not os.path.exists(key_path):
    subprocess.check_call(['ssh-keygen',
                           '-N', '',
                           '-f', key_path],
                          stdin=subprocess.PIPE,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)

  try:
    # Then, spawn the web server for serving the test configuration.
    httpd = subprocess.Popen(['python', '-m', 'debmarshal.web', test],
                             stdout=subprocess.PIPE)
    web_port = httpd.stdout.read()

    try:
      results_queue = Queue.Queue()
      threads = []

      # For each VM that needs to be installed, create a thread to run
      # the installer
      for vm in vms:
        dist = base.findDistribution(config['vms'][vm]['distribution'])

        threads.append(threading.Thread(
            target=dist.doInstall,
            args=(test,
                  vm,
                  net_name,
                  net_gate,
                  net_vms[vm][1],
                  web_port,
                  results_queue)))

      # Ready, set, go!
      for t in threads:
        t.start()

      # Wait until all of the threads have completed execution
      for t in threads:
        t.join()

      return prepareSummary(results_queue, start)
    finally:
      os.kill(httpd.pid, signal.SIGTERM)
  finally:
    privops.call('destroyNetwork', net_name)
Example #5
0
  def doInstall(test, vm, net_name, net_gateway, mac, web_port, results_queue):
    """Start and monitor an unattended Ubuntu install.

    This function will start an unattended Ubuntu install, running in
    a VM, as part of a debmarshal test. It will also monitor that
    install to completion.

    This is intended to be run as a separate thread of execution, so
    that many installs can run in parallel.

    Its success or failure is reported back to the spawning process
    through the results_queue.

    Args:
      test: A path to a debmarshal test
      vm: The hostname of the vm within the test to install
      net_name: The name of a debmarshal network configured for this VM.
      net_gateway: The gateway of the debmarshal network.
      mac: The MAC address of this VM.
      web_port: The port the test is being served over. The spawning
        process should be serving the directory containing the
        debmarshal test over HTTP.
      results_queue: A Queue.Queue object that doInstall will store its
        success or failure into that
    """
    try:
      config = yaml.safe_load(open(os.path.join(test, 'config.yml')))

      domain = config['domain']

      vm_config = config['vms'][vm]

      memory, suite, arch, disk_size, preseed_path = parseConfig(
        test, vm, vm_config)

      deb_arch = arch if arch != 'x86_64' else 'amd64'

      disk_path = Ubuntu.diskPath(vm, domain, test, vm_config)
      disk_dir = os.path.dirname(disk_path)
      if not os.path.exists(disk_dir):
        os.makedirs(disk_dir)

      disk_lock = open(disk_path + '.lock', 'w')
      fcntl.lockf(disk_lock, fcntl.LOCK_EX)

      if os.path.exists(disk_path):
        results_queue.put((test, vm, True, 'cached'))
        return

      base.createSparseFile(disk_path, disk_size)

      try:
        kernel, initrd = loadKernel(suite, deb_arch)

        cmdline = genCommandLine(preseed_path)
        cmdline += ' preseed/url=http://%s:%s/%s.preseed' % (
          net_gateway, web_port, vm)
        cmdline += ' mirror/http/hostname=%s:9999' % net_gateway
        cmdline += ' mirror/http/directory=/ubuntu'
        cmdline += ' mirror/http/proxy='

        dom_name = privops.call('createDomain',
                                memory,
                                [disk_path],
                                net_name,
                                mac,
                                'qemu',
                                arch,
                                {'kernel': kernel,
                                 'initrd': initrd,
                                 'cmdline': cmdline,
                                 'on_reboot': 'destroy'})

        # Now wait for the install to finish...
        #
        # libvirt has an API for integration with somebody else's main
        # loop. Unfortunately, they forgot to make it usable by
        # humans. libvirt-glib in Debian experimental might be a good
        # jumping off point.
        #
        # TODO(ebroder): Figure out how to use some sort of select()
        #   loop instead of a while-sleep loop.
        while True:
          time.sleep(10)

          if dom_name not in qemu.QEMU.listDomains():
            break

        results_queue.put((test, vm, True, None))
      except:
        os.remove(disk_path)
        raise
    except:
      results_queue.put((test, vm, False, traceback.format_exc()))
Example #6
0
def runTest(test):
    """Actually run a debmarshal test.

  Args:
    Path to the test to run.
  """
    start = time.time()

    # First, load the configuration
    config = yaml.safe_load(open(os.path.join(test, "config.yml")))

    # Next, network configuration. Configure the network as it will be
    # for the test run.
    vms = config["vms"].keys()
    net_name, net_gate, net_mask, net_vms = privops.call("createNetwork", vms)

    try:
        # Then, spawn the web server for serving the test configuration.
        httpd = subprocess.Popen(["python", "-m", "debmarshal.web", test], stdout=subprocess.PIPE)
        web_port = httpd.stdout.read()

        domain = config["domain"]

        try:
            images = {}
            domains = {}

            for vm in vms:
                vm_config = config["vms"][vm]
                dist = base.findDistribution(vm_config["distribution"])
                pristine_disk_path = dist.diskPath(vm, domain, test, vm_config)

                fd, disk_path = tempfile.mkstemp()
                os.close(fd)
                subprocess.check_call(
                    ["cp", "--sparse=always", pristine_disk_path, disk_path],
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                )
                images[vm] = disk_path

            for vm in vms:
                vm_config = config["vms"][vm]
                memory = vm_config.get("memory", "128M")
                arch = vm_config.get("arch", "")

                domains[vm] = privops.call(
                    "createDomain", memory, [images[vm]], net_name, net_vms[vm][1], "qemu", arch, {}
                )

            # Wait for the master VM to boot up, then run the test
            key_path = os.path.join(test, "id_rsa")
            master = vms[0]
            master_ip = net_vms[master][0]
            while True:
                if not subprocess.call(
                    ["ssh", "-i", key_path, "-o", "ConnectTimeout=1", "-l", "root", master_ip, "true"],
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                ):
                    break
                else:
                    time.sleep(5)

            subprocess.check_call(
                [
                    "ssh",
                    "-i",
                    key_path,
                    "-l",
                    "root",
                    master_ip,
                    "wget",
                    "-N",
                    "-O",
                    "/root/script",
                    "http://%s:%s/script" % (net_gate, web_port),
                ],
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            ret = subprocess.call(
                ["ssh", "-i", key_path, "-l", "root", master_ip, "/root/script", str(web_port)],
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            print ret

        finally:
            for domain in domains.values():
                privops.call("destroyDomain", domain, "qemu")

            for image in images.values():
                os.unlink(image)

            os.kill(httpd.pid, signal.SIGTERM)
    finally:
        privops.call("destroyNetwork", net_name)
Example #7
0
def prepareTest(test):
    """Prepare the disk image for a single test.

  Args:
    Path to a debmarshal test.
  """
    start = time.time()

    # First, load the configuration
    config = yaml.safe_load(open(os.path.join(test, "config.yml")))

    # Next, network configuration. Configure the network as it will be
    # for the test run.
    vms = config["vms"].keys()
    net_name, net_gate, net_mask, net_vms = privops.call("createNetwork", vms)

    # If there's not already an ssh key packaged with the test to use,
    # generate one.
    key_path = os.path.join(test, "id_rsa")
    if not os.path.exists(key_path):
        subprocess.check_call(
            ["ssh-keygen", "-N", "", "-f", key_path],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )

    try:
        # Then, spawn the web server for serving the test configuration.
        httpd = subprocess.Popen(["python", "-m", "debmarshal.web", test], stdout=subprocess.PIPE)
        web_port = httpd.stdout.read()

        try:
            results_queue = Queue.Queue()
            threads = []

            # For each VM that needs to be installed, create a thread to run
            # the installer
            for vm in vms:
                dist = base.findDistribution(config["vms"][vm]["distribution"])

                threads.append(
                    threading.Thread(
                        target=dist.doInstall,
                        args=(test, vm, net_name, net_gate, net_vms[vm][1], web_port, results_queue),
                    )
                )

            # Ready, set, go!
            for t in threads:
                t.start()

            # Wait until all of the threads have completed execution
            for t in threads:
                t.join()

            return prepareSummary(results_queue, start)
        finally:
            os.kill(httpd.pid, signal.SIGTERM)
    finally:
        privops.call("destroyNetwork", net_name)
Example #8
0
    def doInstall(test, vm, net_name, net_gateway, mac, web_port,
                  results_queue):
        """Start and monitor an unattended Ubuntu install.

    This function will start an unattended Ubuntu install, running in
    a VM, as part of a debmarshal test. It will also monitor that
    install to completion.

    This is intended to be run as a separate thread of execution, so
    that many installs can run in parallel.

    Its success or failure is reported back to the spawning process
    through the results_queue.

    Args:
      test: A path to a debmarshal test
      vm: The hostname of the vm within the test to install
      net_name: The name of a debmarshal network configured for this VM.
      net_gateway: The gateway of the debmarshal network.
      mac: The MAC address of this VM.
      web_port: The port the test is being served over. The spawning
        process should be serving the directory containing the
        debmarshal test over HTTP.
      results_queue: A Queue.Queue object that doInstall will store its
        success or failure into that
    """
        try:
            config = yaml.safe_load(open(os.path.join(test, 'config.yml')))

            domain = config['domain']

            vm_config = config['vms'][vm]

            memory, suite, arch, disk_size, preseed_path = parseConfig(
                test, vm, vm_config)

            deb_arch = arch if arch != 'x86_64' else 'amd64'

            disk_path = Ubuntu.diskPath(vm, domain, test, vm_config)
            disk_dir = os.path.dirname(disk_path)
            if not os.path.exists(disk_dir):
                os.makedirs(disk_dir)

            disk_lock = open(disk_path + '.lock', 'w')
            fcntl.lockf(disk_lock, fcntl.LOCK_EX)

            if os.path.exists(disk_path):
                results_queue.put((test, vm, True, 'cached'))
                return

            base.createSparseFile(disk_path, disk_size)

            try:
                kernel, initrd = loadKernel(suite, deb_arch)

                cmdline = genCommandLine(preseed_path)
                cmdline += ' preseed/url=http://%s:%s/%s.preseed' % (
                    net_gateway, web_port, vm)
                cmdline += ' mirror/http/hostname=%s:9999' % net_gateway
                cmdline += ' mirror/http/directory=/ubuntu'
                cmdline += ' mirror/http/proxy='

                dom_name = privops.call(
                    'createDomain', memory, [disk_path], net_name, mac, 'qemu',
                    arch, {
                        'kernel': kernel,
                        'initrd': initrd,
                        'cmdline': cmdline,
                        'on_reboot': 'destroy'
                    })

                # Now wait for the install to finish...
                #
                # libvirt has an API for integration with somebody else's main
                # loop. Unfortunately, they forgot to make it usable by
                # humans. libvirt-glib in Debian experimental might be a good
                # jumping off point.
                #
                # TODO(ebroder): Figure out how to use some sort of select()
                #   loop instead of a while-sleep loop.
                while True:
                    time.sleep(10)

                    if dom_name not in qemu.QEMU.listDomains():
                        break

                results_queue.put((test, vm, True, None))
            except:
                os.remove(disk_path)
                raise
        except:
            results_queue.put((test, vm, False, traceback.format_exc()))