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.")
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.")
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()
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"))
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)
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"))
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)
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)})
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")