Exemple #1
0
    def probe_dhcp(self):
        """Find all the interfaces on this rack controller and probe for
        DHCP servers.
        """
        client = yield self._tryGetClient()
        if client is None:
            maaslog.error(
                "Can't initiate DHCP probe; no RPC connection to region.")
            return

        # Iterate over interfaces and probe each one.
        interfaces = yield self._get_interfaces()
        self.log("Probe for external DHCP servers started on interfaces: %s." %
                 (", ".join(interfaces)))
        for interface in interfaces:
            try:
                servers = yield maybeDeferred(probe_interface, interface)
            except socket.error as e:
                error = (
                    "Failed to probe for external DHCP servers on interface "
                    "'%s'." % interface)
                if is_dev_environment():
                    error += " (Did you configure authbind per HACKING.rst?)"
                self.err(e, error)
                continue
            else:
                if len(servers) > 0:
                    # XXX For now, only send the region one server, since
                    # it can only track one per VLAN (this could be considered
                    # a bug).
                    yield self._inform_region_of_dhcp(client, interface,
                                                      servers.pop())
                else:
                    yield self._inform_region_of_dhcp(client, interface, None)
        self.log("External DHCP probe complete.")
Exemple #2
0
 def _loadSettings(self):
     # Load the settings from rackd.conf.
     with ClusterConfiguration.open() as config:
         settings.DEBUG = config.debug
     # Debug mode is always on in the development environment.
     if is_dev_environment():
         settings.DEBUG = True
Exemple #3
0
def is_dev_environment():
    """Is this the development environment, or production?

    Lazy import to avoid circular import issues.
    """
    from provisioningserver.config import is_dev_environment
    return is_dev_environment()
Exemple #4
0
def sudo_write_file(filename, contents, mode=0o644):
    """Write (or overwrite) file as root.  USE WITH EXTREME CARE.

    Runs an atomic update using non-interactive `sudo`.  This will fail if
    it needs to prompt for a password.

    When running in a snap or devel mode, this function calls
    `atomic_write` directly.

    :type contents: `bytes`.
    """
    from provisioningserver.config import is_dev_environment

    if not isinstance(contents, bytes):
        raise TypeError("Content must be bytes, got: %r" % (contents, ))
    if snappy.running_in_snap():
        atomic_write(contents, filename, mode=mode)
    else:
        maas_write_file = get_library_script_path("maas-write-file")
        command = _with_dev_python(maas_write_file, filename, "%.4o" % mode)
        if not is_dev_environment():
            command = sudo(command)
        proc = Popen(command, stdin=PIPE)
        stdout, stderr = proc.communicate(contents)
        if proc.returncode != 0:
            raise ExternalProcessError(proc.returncode, command, stderr)
Exemple #5
0
def _with_dev_python(*command):
    # Avoid circular imports.
    from provisioningserver.config import is_dev_environment
    if is_dev_environment():
        from maastesting import root
        interpreter = os.path.join(root, "bin", "py")
        command = interpreter, *command
    return command
Exemple #6
0
def get_resources_bin_path():
    """Return the path of the resources binary."""
    if is_dev_environment():
        path = "src/machine-resources/bin"
    else:
        prefix = SnapPaths.from_environ().snap or ""
        path = f"{prefix}/usr/share/maas/machine-resources"
    return os.path.join(path, get_architecture())
Exemple #7
0
def run():
    is_snap = "SNAP" in os.environ
    is_devenv = is_dev_environment()
    if not is_devenv:
        check_user()
        if not is_snap:
            set_group()
        set_umask()
    run_django(is_snap, is_devenv)
Exemple #8
0
 def monitorServices(self):
     """Monitors all of the external services and makes sure they
     stay running.
     """
     if is_dev_environment():
         log.msg("Skipping check of services; they're not running under "
                 "the supervision of systemd.")
     else:
         d = service_monitor.ensureServices()
         d.addCallback(self._updateDatabase)
         d.addErrback(log.err,
                      "Failed to monitor services and update database.")
         return d
Exemple #9
0
def get_maas_common_command():
    """Return path to the maas-rack command.

    In production mode this will just return 'maas-rack', but in
    development mode it will return the path for the current development
    environment.
    """
    # Avoid circular imports.
    from provisioningserver.config import is_dev_environment
    if is_dev_environment():
        from maastesting import root
        return os.path.join(root, "bin", "maas-common")
    else:
        return os.path.join(get_path("/usr/lib/maas"), "maas-common")
Exemple #10
0
    def _reconfigureLogging(self):
        # Reconfigure the logging based on the debug mode of Django.
        from django.conf import settings
        if settings.DEBUG:
            # In debug mode, force logging to debug mode.
            logger.set_verbosity(3)

            # When not in the developer environment, patch Django to not
            # use the debug cursor. This is needed or Django will store in
            # memory every SQL query made.
            from provisioningserver.config import is_dev_environment
            if not is_dev_environment():
                from django.db.backends.base import base
                from django.db.backends.utils import CursorWrapper
                base.BaseDatabaseWrapper.make_debug_cursor = (
                    lambda self, cursor: CursorWrapper(cursor, self))
Exemple #11
0
def get_maas_common_command():
    """Return path to the maas-rack command.

    In production mode this will just return 'maas-rack', but in
    development mode it will return the path for the current development
    environment.
    """
    # Avoid circular imports.
    from provisioningserver.config import is_dev_environment
    if is_dev_environment():
        from maastesting import root
        return os.path.join(root, 'bin/maas-common')
    elif snappy.running_in_snap():
        # there's no maas-common in the snap as maas-rack is always present
        return os.path.join(snappy.get_snap_path(), 'bin/maas-rack')
    else:
        return get_path('usr/lib/maas/maas-common')
Exemple #12
0
    def _getInterfacesForNeighbourDiscovery(self, interfaces: dict,
                                            monitoring_state: dict):
        """Return the interfaces which will be used for neighbour discovery.

        :return: The set of interface names to run neighbour discovery on.
        """
        # Don't observe interfaces when running the test suite/dev env.
        # In addition, if we don't own the lock, we should not be monitoring
        # any interfaces.
        if is_dev_environment() or not self._locked or interfaces is None:
            return set()
        monitored_interfaces = {
            ifname
            for ifname in interfaces
            if (ifname in monitoring_state
                and monitoring_state[ifname].get('neighbour', False) is True)
        }
        return monitored_interfaces
Exemple #13
0
def run():
    is_snap = "SNAP" in os.environ
    is_devenv = is_dev_environment()

    if not is_devenv:
        if is_snap:
            os.environ.update({
                "MAAS_PATH":
                os.environ["SNAP"],
                "MAAS_ROOT":
                os.environ["SNAP_DATA"],
                "MAAS_DATA":
                os.path.join(os.environ["SNAP_COMMON"], "maas"),
                "MAAS_CLUSTER_CONFIG":
                os.path.join(os.environ["SNAP_DATA"], "rackd.conf"),
            })

        users = ["root"]
        # Allow dhcpd user to call dhcp-notify, and maas user to call
        # observe-arp.
        if not is_snap and len(sys.argv) > 1:
            if sys.argv[1] == "dhcp-notify":
                users.append("dhcpd")
            if sys.argv[1] == "observe-arp":
                users.append("maas")
            if sys.argv[1] == "observe-beacons":
                users.append("maas")
            if sys.argv[1] == "observe-mdns":
                # Any user can call this. (It might be necessary for a normal
                # user to call this for support/debugging purposes.)
                users.append(None)

        # Only set the group and umask when running as root.
        if check_users(users) == "root":
            if not is_snap:
                set_group()
            set_umask()

    # Run the script.
    # Run the main provisioning script.
    from provisioningserver.__main__ import main

    main()
Exemple #14
0
def get_library_script_path(name):
    """Return path to a "library script".

    By convention (here) scripts are always installed to ``/usr/lib/maas`` on
    the target machine.

    The FHS (Filesystem Hierarchy Standard) defines ``/usr/lib/`` as the
    location for libraries used by binaries in ``/usr/bin`` and ``/usr/sbin``,
    hence the term "library script".

    In production mode this will return ``/usr/lib/maas/$name``, but in
    development mode it will return ``$root/scripts/$name``.
    """
    # Avoid circular imports.
    from provisioningserver.config import is_dev_environment
    if is_dev_environment():
        from maastesting import root
        return os.path.join(root, "scripts", name)
    else:
        return os.path.join(get_path("/usr/lib/maas"), name)
Exemple #15
0
def sudo_delete_file(filename):
    """Delete file as root.  USE WITH EXTREME CARE.

    Runs an atomic update using non-interactive `sudo`.  This will fail if
    it needs to prompt for a password.

    When running in a snap this function calls `atomic_write` directly.
    """
    from provisioningserver.config import is_dev_environment
    if snappy.running_in_snap():
        atomic_delete(filename)
    else:
        maas_delete_file = get_library_script_path("maas-delete-file")
        command = _with_dev_python(maas_delete_file, filename)
        if not is_dev_environment():
            command = sudo(command)
        proc = Popen(command)
        stdout, stderr = proc.communicate()
        if proc.returncode != 0:
            raise ExternalProcessError(proc.returncode, command, stderr)
Exemple #16
0
def call_uec2roottar(root_image_path, root_tgz_path):
    """Invoke `uec2roottar` with the given arguments.

    Here only so tests can stub it out.

    :param root_image_path: Input file.
    :param root_tgz_path: Output file.
    """
    if is_dev_environment():
        # In debug mode this is skipped as it requires the uec2roottar
        # script to have sudo abilities. The root-tgz is created as an
        # empty file so the correct links can be made.
        log.msg(
            "Conversion of root-image to root-tgz is skipped in DEVELOP mode.")
        open(root_tgz_path, "wb").close()
    else:
        call_and_check([
            'sudo', '/usr/bin/uec2roottar',
            '--user=maas',
            root_image_path,
            root_tgz_path,
            ])
Exemple #17
0
 def test_is_dev_environment_returns_true(self):
     self.assertTrue(is_dev_environment())
Exemple #18
0
 def test_is_dev_environment_returns_false(self):
     self.useFixture(ImportErrorFixture('maastesting', 'root'))
     self.assertFalse(is_dev_environment())