def test_undeploy_by_dep_ids(self): """ Test taking down a deployed bundle based on the appserverdeployment id. """ app_dir, bundle_dir = utils.app_and_bundle_dirs(self.app_id, self.bundle_name) self.install_my_bundle() (instance_id, node_name, host_ip, host_port) = \ deploy.start_serving_bundle(self.app_id, self.bundle_name) self.assertTrue(os.path.isdir(bundle_dir)) self.check_can_eventually_load( "http://%s:%s" % (host_ip, host_port), "Welcome to the Django tutorial polls app") zoomdb = StubZoomDB() mydep = zoomdb.add_worker(1, "localhost", "127.0.0.1", host_port) self.assertFalse(deploy.is_port_open(host_port)) deploy.undeploy(zoomdb, self.app_id, dep_ids=[mydep.id], use_subtasks=False, also_update_proxies=False) self.assertTrue(deploy.is_port_open(host_port)) #self.assertFalse(os.path.isdir(app_dir)) self.assertFalse(os.path.isdir(bundle_dir))
def remove_previous_versions(zoomdb, opts): """ Find and remove old instances. """ new_instances = opts["DEPLOYED_WORKERS"] zoomdb.log("New instances: %r." % new_instances) new_instances_by_id = dict((i.id, i) for i in new_instances) active_instances = zoomdb.search_workers(active=True) old_instances = [] for i in active_instances: if i.id not in new_instances_by_id: old_instances.append(i) #DNC:# zoomdb.log("Removing old instances %r." % old_instances) if old_instances: tasklib_deploy.undeploy( zoomdb, opts["APP_ID"], dep_ids=[i.id for i in old_instances], also_update_proxies=False, # proxy already updated in prev step zoombuild_cfg_content=opts["ZOOMBUILD_CFG_CONTENT"], zero_undeploys_ok=True, log_step_events=False) else: zoomdb.log("No old instances found.")
def test_undeploy_with_proxy_update(self): """ Test taking down a deployed bundle and updating the proxy config too. """ app_dir, bundle_dir = utils.app_and_bundle_dirs(self.app_id, self.bundle_name) self.install_my_bundle() (instance_id, node_name, host_ip, host_port) = \ deploy.start_serving_bundle(self.app_id, self.bundle_name) # also add to nginx - fake it for this test here = os.path.abspath(os.path.split(__file__)[0]) fixture_dir = os.path.join(here, '../fixtures') nginx_site_file = os.path.join(taskconfig.NGINX_SITES_ENABLED_DIR, self.app_id) shutil.copyfile(os.path.join(fixture_dir, 'test_deploy_nginx_site'), nginx_site_file) self.check_can_eventually_load( "http://%s:%s" % (host_ip, host_port), "Welcome to the Django tutorial polls app") zoomdb = StubZoomDB() mydep = zoomdb.add_worker(1, "localhost", "127.0.0.1", host_port) self.assertFalse(deploy.is_port_open(host_port)) zcfg_path = os.path.join(fixture_dir, "app", "zoombuild.cfg") zcfg_content = open(zcfg_path).read() # make sure we require proper parameters - skip zoombuild_cfg_content with self.assertRaises(AssertionError): deploy.undeploy(zoomdb, self.app_id, dep_ids=[mydep.id], use_subtasks=False, also_update_proxies=True) deploy.undeploy(zoomdb, self.app_id, dep_ids=[mydep.id], use_subtasks=False, also_update_proxies=True, zoombuild_cfg_content=zcfg_content) self.assertTrue(deploy.is_port_open(host_port)) self.assertFalse(os.path.isdir(bundle_dir)) self.assertFalse(os.path.isfile(nginx_site_file), "Expected nginx site file %s to be gone, but it isn't" % nginx_site_file)
def undeploy(job_id, zoomdb, job_params): """ Take down any running instances of the application. Bundles will remain in bundle storage, but are uninstalled from appservers. Databases and DB users are not affected. :param: job_params["app_id"]: sys id of app to undeploy :param: job_params["bundle_names"]: names of bundles to undeploy. If not provided, all bundles that are part of the given app are undeployed. """ app_id = job_params["app_id"] bundle_ids = job_params["bundle_ids"] use_subtasks = job_params.get("use_subtasks", True) return deploy.undeploy(zoomdb, app_id, bundle_ids, use_subtasks=use_subtasks)
def test_build_and_deploy(self): """Invoke the build and deploy task.""" zoomdb = StubZoomDB() src_repo_type = "git" src_url = "git://github.com/shimon/djangotutorial.git" here = path.abspath(path.split(__file__)[0]) app_fixture = path.join(here, "../fixtures", "app") zcfg_fixture = path.join(app_fixture, "zoombuild.cfg") zoombuild_cfg_content = file(zcfg_fixture).read() self.assertFalse(zoomdb.is_flushed) self.assertEqual(len(zoomdb.get_all_bundles()), 0) self.assertEqual(len(zoomdb.get_project_workers()), 0) self.assertEqual(len(zoomdb.get_project_virtual_hosts()), 1) zoomdb.test_vhosts = ["awesomesite.com", "foo.co.br"] self.assertEqual(len(zoomdb.get_project_virtual_hosts()), 3) deployed_addresses = build_and_deploy.build_and_deploy( zoomdb, self.app_id, src_repo_type, src_url, zoombuild_cfg_content, use_subtasks=False, bundle_storage_engine=bundle_storage_local, ) print "build_and_deploy returned: %r" % deployed_addresses # # call the tasks module directly instead, so we get that tested too. # # actually this doesn't work because of the decorator; doh! # deployed_addresses = builder.build_and_deploy(zoomdb._job_id, zoomdb, # { # "app_id": self.app_id, # "src_url": src_url, # "zoombuild_cfg_content": zoombuild_cfg_content, # }) zoombuild_cfg_output_filename = path.join(self.dir, self.app_id, "zoombuild.cfg") self.assertTrue(path.isfile(zoombuild_cfg_output_filename)) self.assertEqual(file(zoombuild_cfg_output_filename).read(), zoombuild_cfg_content) p = zoomdb.get_project() for attr in ("db_host", "db_name", "db_username", "db_password"): print "project.%s = %s" % (attr, getattr(p, attr)) self.assertTrue(getattr(p, attr)) self.assertTrue(zoomdb.is_flushed) self.assertEqual(len(zoomdb.get_all_bundles()), 1) self.assertEqual(len(zoomdb.get_project_workers()), 1) site_nginx_conf_file = os.path.join(taskconfig.NGINX_SITES_ENABLED_DIR, self.app_id) self.assertTrue( os.path.isfile(site_nginx_conf_file), "expected to find a config file in nginx's " "sites-enabled directory, but didn't", ) # check the deployed app! self.assertEqual(len(deployed_addresses), 1) for (instance_id, node_name, host_ip, host_port) in deployed_addresses: polls_url = "http://%s:%d/polls/" % (host_ip, host_port) print "Testing Polls URL: %s" % polls_url polls_src = urllib.urlopen(polls_url).read() self.assertTrue("No polls are available." in polls_src) # now check the nginx service hosts = zoomdb.get_project_virtual_hosts() # ensure each hostname works! for host in hosts: # GZIP DEBUG# import ipdb; ipdb.set_trace() self.check_can_eventually_load_custom("127.0.0.1", "/polls/", host, "No polls are available.") # for nginx to serve static files, the cust dir has to be # world-read/executable. This should be the default on the # proxy server ONLY. os.chmod(self.dir, 0755) image_src = self.check_can_eventually_load_custom("127.0.0.1", "/static/img/polls.jpg", hosts[0]) local_image_file = os.path.join(app_fixture, "src", "static", "polls.jpg") self.assertEqual(image_src, open(local_image_file).read()) # try a collectstatic-handled file collectstatic_src = self.check_can_eventually_load_custom( "127.0.0.1", "/staticfiles/polls/Lineup.jpg", hosts[0] ) local_collectstatic_file = os.path.join(app_fixture, "src", "polls", "static", "polls", "Lineup.jpg") self.assertEqual(collectstatic_src, open(local_collectstatic_file).read()) # OK, now undeploy. deploy.undeploy(zoomdb, self.app_id, bundle_ids=None, use_subtasks=False) # check that URLs are no longer accessible for (instance_id, node_name, host_ip, host_port) in deployed_addresses: polls_url = "http://%s:%d/polls/" % (host_ip, host_port) with self.assertRaises(IOError): urllib.urlopen(polls_url).read() # check that Nginx conf file is gone self.assertFalse(os.path.isfile(site_nginx_conf_file), "expected nginx config file gone") # check that supervisor files are gone for fname in os.listdir(taskconfig.SUPERVISOR_APP_CONF_DIR): self.assertFalse( fname.startswith("%s." % self.app_id), "There is a lingering supervisor config " "file: %s" % fname ) # check that DB still exists though dblist = utils.local("psql -l -U nrweb | awk '{print $1}'") self.assertTrue(self.app_id in dblist.splitlines())