Beispiel #1
0
    def destroy_environment(self):
        """Shutdown the machine environment.
        """
        # Stop all the containers
        log.info("Destroying unit containers...")
        yield self._destroy_containers()

        # Stop the machine agent
        log.debug("Stopping machine agent...")
        agent = ManagedMachineAgent(self._qualified_name)
        yield agent.stop()

        # Stop the storage server
        log.debug("Stopping storage server...")
        storage_server = StorageServer(self._qualified_name)
        yield storage_server.stop()

        # Stop zookeeper
        log.debug("Stopping zookeeper...")
        zookeeper_dir = os.path.join(self._directory, "zookeeper")
        zookeeper = Zookeeper(zookeeper_dir, None)
        yield zookeeper.stop()

        # Clean out local state
        yield self.save_state(False)

        # Don't stop the network since we're using the default libvirt
        log.debug("Environment destroyed.")
Beispiel #2
0
    def destroy_environment(self):
        """Shutdown the machine environment.
        """
        # Stop all the containers
        log.info("Destroying unit containers...")
        yield self._destroy_containers()

        # Stop the machine agent
        log.debug("Stopping machine agent...")
        pid_file = os.path.join(self._directory, "machine-agent.pid")
        agent = ManagedMachineAgent(pid_file)
        yield agent.stop()

        # Stop the storage server
        log.debug("Stopping storage server...")
        pid_file = os.path.join(self._directory, "storage-server.pid")
        storage_server = StorageServer(pid_file)
        yield storage_server.stop()

        # Stop zookeeper
        log.debug("Stopping zookeeper...")
        zookeeper_dir = os.path.join(self._directory, "zookeeper")
        zookeeper = Zookeeper(zookeeper_dir, None)
        yield zookeeper.stop()

        # Clean out local state
        yield self.save_state(False)

        # Don't stop the network since we're using the default libvirt
        log.debug("Environment destroyed.")
Beispiel #3
0
    def test_managed_agent_root(self):
        juju_directory = self.makeDir()
        log_file = tempfile.mktemp()

        # The pid file and log file get written as root
        def cleanup_root_file(cleanup_file):
            subprocess.check_call(
                ["sudo", "rm", "-f", cleanup_file], stderr=subprocess.STDOUT)
        self.addCleanup(cleanup_root_file, log_file)

        agent = ManagedMachineAgent(
            "test-ns", machine_id="0",
            log_file=log_file,
            juju_series="precise",
            zookeeper_hosts=get_test_zookeeper_address(),
            juju_directory=juju_directory)

        agent.agent_module = "juju.agents.dummy"
        self.assertFalse((yield agent.is_running()))
        yield agent.start()
        # Give a moment for the process to start and write its config
        yield self.sleep(0.1)
        self.assertTrue((yield agent.is_running()))

        # running start again is fine, detects the process is running
        yield agent.start()
        yield agent.stop()
        self.assertFalse((yield agent.is_running()))

        # running stop again is fine, detects the process is stopped.
        yield agent.stop()
Beispiel #4
0
    def test_managed_agent_args(self):

        captured_args = []

        def intercept_args(args):
            captured_args.extend(args)
            return True

        self.patch(subprocess, "check_call", intercept_args)

        juju_directory = self.makeDir()
        pid_file = self.makeFile()
        log_file = self.makeFile()

        agent = ManagedMachineAgent(pid_file,
                                    get_test_zookeeper_address(),
                                    juju_directory=juju_directory,
                                    log_file=log_file,
                                    juju_unit_namespace="ns1",
                                    juju_origin="lp:juju/trunk")

        mock_agent = self.mocker.patch(agent)
        mock_agent.is_running()
        self.mocker.result(succeed(False))
        self.mocker.replay()

        self.assertEqual(agent.juju_origin, "lp:juju/trunk")
        yield agent.start()

        # Verify machine agent environment
        env_vars = dict(
            [arg.split("=") for arg in captured_args if "=" in arg])
        env_vars.pop("PYTHONPATH")
        self.assertEqual(
            env_vars,
            dict(JUJU_ZOOKEEPER=get_test_zookeeper_address(),
                 JUJU_MACHINE_ID="0",
                 JUJU_HOME=juju_directory,
                 JUJU_ORIGIN="lp:juju/trunk",
                 JUJU_UNIT_NS="ns1"))
Beispiel #5
0
    def test_managed_agent_root(self):
        juju_directory = self.makeDir()
        pid_file = tempfile.mktemp()
        log_file = tempfile.mktemp()

        # The pid file and log file get written as root
        def cleanup_root_file(cleanup_file):
            subprocess.check_call(
                ["sudo", "rm", "-f", cleanup_file], stderr=subprocess.STDOUT)
        self.addCleanup(cleanup_root_file, pid_file)
        self.addCleanup(cleanup_root_file, log_file)

        agent = ManagedMachineAgent(
            pid_file, machine_id="0", log_file=log_file,
            zookeeper_hosts=get_test_zookeeper_address(),
            juju_directory=juju_directory)

        agent.agent_module = "juju.agents.dummy"
        self.assertFalse((yield agent.is_running()))
        yield agent.start()

        # Give a moment for the process to start and write its config
        yield self.sleep(0.1)
        self.assertTrue((yield agent.is_running()))

        # running start again is fine, detects the process is running
        yield agent.start()
        yield agent.stop()
        self.assertFalse((yield agent.is_running()))

        # running stop again is fine, detects the process is stopped.
        yield agent.stop()

        self.assertFalse(os.path.exists(pid_file))

        # Stop raises runtime error if the process doesn't match up.
        with open(pid_file, "w") as pid_handle:
            pid_handle.write("1")
        self.assertFailure(agent.stop(), RuntimeError)
Beispiel #6
0
    def test_managed_agent_args(self):

        captured_args = []

        def intercept_args(args):
            captured_args.extend(args)
            return True

        self.patch(subprocess, "check_call", intercept_args)

        juju_directory = self.makeDir()
        pid_file = self.makeFile()
        log_file = self.makeFile()

        agent = ManagedMachineAgent(
            pid_file, get_test_zookeeper_address(),
            juju_directory=juju_directory,
            log_file=log_file, juju_unit_namespace="ns1",
            juju_origin="lp:juju/trunk")

        mock_agent = self.mocker.patch(agent)
        mock_agent.is_running()
        self.mocker.result(succeed(False))
        self.mocker.replay()

        self.assertEqual(agent.juju_origin, "lp:juju/trunk")
        yield agent.start()

        # Verify machine agent environment
        env_vars = dict(
            [arg.split("=") for arg in captured_args if "=" in arg])
        env_vars.pop("PYTHONPATH")
        self.assertEqual(
            env_vars,
            dict(JUJU_ZOOKEEPER=get_test_zookeeper_address(),
                 JUJU_MACHINE_ID="0",
                 JUJU_HOME=juju_directory,
                 JUJU_ORIGIN="lp:juju/trunk",
                 JUJU_UNIT_NS="ns1"))
Beispiel #7
0
    def test_managed_agent_root(self):
        juju_directory = self.makeDir()
        pid_file = tempfile.mktemp()
        log_file = tempfile.mktemp()

        # The pid file and log file get written as root
        def cleanup_root_file(cleanup_file):
            subprocess.check_call(["sudo", "rm", "-f", cleanup_file],
                                  stderr=subprocess.STDOUT)

        self.addCleanup(cleanup_root_file, pid_file)
        self.addCleanup(cleanup_root_file, log_file)

        agent = ManagedMachineAgent(
            pid_file,
            machine_id="0",
            log_file=log_file,
            zookeeper_hosts=get_test_zookeeper_address(),
            juju_directory=juju_directory)

        agent.agent_module = "juju.agents.dummy"
        self.assertFalse((yield agent.is_running()))
        yield agent.start()

        # Give a moment for the process to start and write its config
        yield self.sleep(0.1)
        self.assertTrue((yield agent.is_running()))

        # running start again is fine, detects the process is running
        yield agent.start()
        yield agent.stop()
        self.assertFalse((yield agent.is_running()))

        # running stop again is fine, detects the process is stopped.
        yield agent.stop()

        self.assertFalse(os.path.exists(pid_file))

        # Stop raises runtime error if the process doesn't match up.
        with open(pid_file, "w") as pid_handle:
            pid_handle.write("1")
        self.assertFailure(agent.stop(), RuntimeError)
Beispiel #8
0
    def test_managed_agent_config(self):
        subprocess_calls = []

        def intercept_args(args, **kwargs):
            subprocess_calls.append(args)
            self.assertEquals(args[0], "sudo")
            if args[1] == "cp":
                return real_check_call(args[1:], **kwargs)
            return 0

        real_check_call = self.patch(subprocess, "check_call", intercept_args)
        init_dir = self.makeDir()
        self.patch(UpstartService, "init_dir", init_dir)

        # Mock out the repeated checking for unstable pid, after an initial
        # stop/waiting to induce the actual start
        getProcessOutput = self.mocker.replace(
            "twisted.internet.utils.getProcessOutput")
        getProcessOutput("/sbin/status", ["juju-ns1-machine-agent"])
        self.mocker.result(succeed("stop/waiting"))
        for _ in range(5):
            getProcessOutput("/sbin/status", ["juju-ns1-machine-agent"])
            self.mocker.result(succeed("start/running 123"))
        self.mocker.replay()

        juju_directory = self.makeDir()
        log_file = self.makeFile()
        agent = ManagedMachineAgent(
            "ns1",
            get_test_zookeeper_address(),
            juju_series="precise",
            juju_directory=juju_directory,
            log_file=log_file,
            juju_origin="lp:juju/trunk")

        try:
            os.remove("/tmp/juju-ns1-machine-agent.output")
        except OSError:
            pass  # just make sure it's not there, so the .start()
                  # doesn't insert a spurious rm

        yield agent.start()

        conf_dest = os.path.join(
            init_dir, "juju-ns1-machine-agent.conf")
        chmod, start = subprocess_calls[1:]
        self.assertEquals(chmod, ("sudo", "chmod", "644", conf_dest))
        self.assertEquals(
            start, ("sudo", "/sbin/start", "juju-ns1-machine-agent"))

        env = []
        with open(conf_dest) as f:
            for line in f:
                if line.startswith("env"):
                    env.append(line[4:-1].split("=", 1))
                if line.startswith("exec"):
                    exec_ = line[5:-1]

        expect_exec = (
            "/usr/bin/python -m juju.agents.machine --nodaemon --logfile %s "
            "--session-file /var/run/juju/ns1-machine-agent.zksession "
            ">> /tmp/juju-ns1-machine-agent.output 2>&1"
            % log_file)
        self.assertEquals(exec_, expect_exec)

        env = dict((k, v.strip('"')) for (k, v) in env)
        self.assertEquals(env, {
            "JUJU_ZOOKEEPER": get_test_zookeeper_address(),
            "JUJU_MACHINE_ID": "0",
            "JUJU_HOME": juju_directory,
            "JUJU_ORIGIN": "lp:juju/trunk",
            "JUJU_UNIT_NS": "ns1",
            "JUJU_SERIES": "precise",
            "PYTHONPATH": ":".join(sys.path)})
Beispiel #9
0
class MachineProvider(MachineProviderBase):
    """LXC/Ubuntu local provider.

    Only the host machine is utilized.
    """

    def __init__(self, environment_name, config):
        super(MachineProvider, self).__init__(environment_name, config)
        self._qualified_name = self._get_qualified_name()
        self._directory = os.path.join(
            self.config["data-dir"], self._qualified_name)

    def get_placement_policy(self):
        """Local dev supports only one unit placement policy."""
        if self.config.get("placement", LOCAL_POLICY) != LOCAL_POLICY:
            raise ProviderError(
                "Unsupported placement policy for local provider")
        return LOCAL_POLICY

    @property
    def provider_type(self):
        return "local"

    @inlineCallbacks
    def bootstrap(self):
        """Bootstrap a local development environment.
        """
        # Check for existing environment
        state = yield self.load_state()
        if state is not False:
            raise ProviderError("Environment already bootstrapped")

        # Check for required packages
        log.info("Checking for required packages...")
        missing = check_packages(*REQUIRED_PACKAGES)
        if missing:
            raise ProviderError("Missing packages %s" % (
                ", ".join(sorted(list(missing)))))

        # Get/create directory for zookeeper and files
        zookeeper_dir = os.path.join(self._directory, "zookeeper")
        if not os.path.exists(zookeeper_dir):
            os.makedirs(zookeeper_dir)

        # Start networking, and get an open port.
        log.info("Starting networking...")
        net = Network("default", subnet=122)

        # Start is a noop if its already started, which it is by default,
        # per libvirt-bin package installation
        yield net.start()
        net_attributes = yield net.get_attributes()
        port = get_open_port(net_attributes["ip"]["address"])

        # Start zookeeper
        log.info("Starting zookeeper...")
        # Run zookeeper as the current user, unless we're being run as root
        # in which case run zookeeper as the 'zookeeper' user.
        zookeeper_user = None
        if os.geteuid() == 0:
            zookeeper_user = "******"
        zookeeper = Zookeeper(zookeeper_dir,
                              port=port,
                              host=net_attributes["ip"]["address"],
                              user=zookeeper_user, group=zookeeper_user)

        yield zookeeper.start()

        # Starting provider storage server
        log.info("Starting storage server...")
        storage_server = StorageServer(
            pid_file=os.path.join(self._directory, "storage-server.pid"),
            storage_dir=os.path.join(self._directory, "files"),
            host=net_attributes["ip"]["address"],
            port=get_open_port(net_attributes["ip"]["address"]),
            log_file=os.path.join(self._directory, "storage-server.log"))
        yield storage_server.start()

        # Save the zookeeper start to provider storage.
        yield self.save_state({"zookeeper-instances": ["local"],
                               "zookeeper-address": zookeeper.address})

        # Initialize the zookeeper state
        log.debug("Initializing state...")
        admin_identity = make_identity(
            "admin:%s" % self.config["admin-secret"])
        client = ZookeeperClient(zookeeper.address)
        yield client.connect()
        hierarchy = StateHierarchy(client, admin_identity, "local", "local")
        yield hierarchy.initialize()

        # Store user credentials from the running user
        try:
            public_key = get_user_authorized_keys(self.config)
            public_key = public_key.strip()
        except LookupError, e:
            raise ProviderError(str(e))

        # Startup the machine agent
        pid_file = os.path.join(self._directory, "machine-agent.pid")
        log_file = os.path.join(self._directory, "machine-agent.log")

        juju_origin = self.config.get("juju-origin")
        agent = ManagedMachineAgent(pid_file,
                                    zookeeper_hosts=zookeeper.address,
                                    machine_id="0",
                                    juju_directory=self._directory,
                                    log_file=log_file,
                                    juju_origin=juju_origin,
                                    juju_unit_namespace=self._qualified_name,
                                    public_key=public_key)
        log.info(
            "Starting machine agent (origin: %s)... ", agent.juju_origin)
        yield agent.start()

        log.info("Environment bootstrapped")