Refactor code

_add_recipe and _add_run_list are combined, _run_chef_client are
modified, and multi-thread code are put in a single function.

Change-Id: I12c2418546f366b484acc1258d10cc5b6554af8a
This commit is contained in:
Changbin Liu 2013-05-23 14:39:26 -04:00
parent deaf72210d
commit 9dab6cc172
1 changed files with 56 additions and 40 deletions

View File

@ -47,6 +47,7 @@ class Orchestrator(object):
num_workers,
chef_repo,
chef_repo_branch,
sequential,
user='ubuntu',
image='3ab46178-eaae-46f0-8c13-6aad4d62ecde',
flavor=3,
@ -66,6 +67,8 @@ class Orchestrator(object):
@param num_workers: how many worker nodes you'd like
@param chef_repo: chef repository location
@param chef_repo_branch: which branch to use in repo
@param sequential: whether run threads in sequential or parallel
(for accelerating)
@param user: username (with root permission) for all servers
@param image: default u1204-130508-gv
@param flavor: default medium
@ -94,6 +97,7 @@ class Orchestrator(object):
self.num_workers = num_workers
self.chef_repo = chef_repo
self.chef_repo_branch = chef_repo_branch
self.sequential = sequential
self.user = user
self.image = image
self.flavor = flavor
@ -287,8 +291,8 @@ class Orchestrator(object):
environment to be self.prefix
"""
threads = []
ipaddrs = ([self._chefserver_ip, self._gateway_ip, self._controller_ip]
+ self._worker_ips)
ipaddrs = ([self._chefserver_ip, self._gateway_ip,
self._controller_ip] + self._worker_ips)
hostnames = ([self._chefserver_name, self._gateway_name,
self._controller_name] + self._worker_names)
for (ipaddr, hostname) in zip(ipaddrs, hostnames):
@ -300,9 +304,7 @@ class Orchestrator(object):
kwargs={"screen_output": True,
"agent_forwarding": True})
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
self._run_threads(threads)
def _deploy_network_vxlan(self):
"""
@ -310,8 +312,12 @@ class Orchestrator(object):
i.e., build VXLAN tunnels with gateway as layer-2 hub and other VMs
as spokes, and assign ip address and netmask
"""
self._add_recipe('recipe[openvswitch::network-vxlan]')
self._run_chef_client()
hostnames = ([self._chefserver_name, self._gateway_name,
self._controller_name] + self._worker_names)
self._add_run_list(hostnames, 'recipe[openvswitch::network-vxlan]')
ipaddrs = ([self._chefserver_ip, self._gateway_ip,
self._controller_ip] + self._worker_ips)
self._run_chef_client(ipaddrs)
def _deploy_dnsmasq(self):
"""
@ -319,39 +325,40 @@ class Orchestrator(object):
i.e., install and config on dnsmasq on gateway node, and point all
VMs to gateway as nameserver
"""
self._add_recipe('recipe[openvswitch::dnsmasq]')
self._run_chef_client()
def _add_recipe(self, recipe):
"""
for each server, add a recipe its run_list
@param recipe: name of the recipe
"""
threads = []
hostnames = ([self._chefserver_name, self._gateway_name,
self._controller_name] + self._worker_names)
self._add_run_list(hostnames, 'recipe[openvswitch::dnsmasq]')
ipaddrs = ([self._chefserver_ip, self._gateway_ip,
self._controller_ip] + self._worker_ips)
self._run_chef_client(ipaddrs)
def _add_run_list(self, hostnames, item):
"""
for each server, add an item to its run_list
@param hostnames: hostnames of specified servers
@param item: name of the item (e.g., recipe, role, etc)
"""
threads = []
for hostname in hostnames:
uri = self.user + '@' + self._chefserver_ip
command = "/usr/bin/knife node run_list add %s %s" % (
hostname, recipe)
hostname, item)
thread = threading.Thread(target=cmd.ssh,
args=(uri, command),
kwargs={"screen_output": True,
"agent_forwarding": True})
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
self._run_threads(threads)
def _run_chef_client(self):
def _run_chef_client(self, ipaddrs):
"""
for each server, run the chef-client for all specified cookbooks in its
run_list
for each server in the address list, run chef-client for all
specified cookbooks in its run_list
@param param: ip addresses of the servers
"""
threads = []
ipaddrs = ([self._chefserver_ip, self._gateway_ip,
self._controller_ip] + self._worker_ips)
for ipaddr in ipaddrs:
uri = self.user + '@' + ipaddr
command = "sudo chef-client"
@ -360,16 +367,23 @@ class Orchestrator(object):
kwargs={"screen_output": True,
"agent_forwarding": True})
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
self._run_threads(threads)
def _add_run_list(self, hostname, item):
cmd.ssh(self.user + '@' + self._chefserver_ip,
"/usr/bin/knife node run_list add %s %s" % (
hostname, item),
screen_output=True,
agent_forwarding=True)
def _run_threads(self, threads):
"""
run threads, whether in a sequential or parallel way
@param threads: the threads to be run
"""
if self.sequential:
for thread in threads:
thread.start()
thread.join()
else:
for thread in threads:
thread.start()
for thread in threads:
thread.join()
def _setup_controller(self):
"""
@ -378,8 +392,7 @@ class Orchestrator(object):
def _setup_workers(self):
"""
deploy workers via misc cookbooks (parallelization via Python
multi-threading or multi-processing)
deploy workers via misc cookbooks
"""
def cleanup(self):
@ -430,9 +443,10 @@ def main():
cleanup = False
chef_repo = "git://github.com/maoy/inception-chef-repo.git"
chef_repo_branch = "master"
sequential = False
try:
optlist, _ = getopt.getopt(sys.argv[1:], 'p:n:',
["shell", "atomic", "cleanup",
["shell", "atomic", "cleanup", "sequential",
"chef-repo=", "chef-repo-branch="])
optdict = dict(optlist)
prefix = optdict['-p']
@ -447,12 +461,14 @@ def main():
chef_repo = optdict["--chef-repo"]
if "--chef-repo-branch" in optdict:
chef_repo_branch = optdict["--chef-repo-branch"]
if "--sequential" in optdict:
sequential = True
except Exception:
print traceback.format_exc()
usage()
sys.exit(1)
orchestrator = Orchestrator(prefix, num_workers, chef_repo,
chef_repo_branch)
chef_repo_branch, sequential)
if shell:
# give me a ipython shell
IPython.embed()
@ -466,7 +482,7 @@ def main():
def usage():
print """
python %s -p <prefix> -n <num_workers> [--shell] [--atomic] [--cleanup]
[--chef-repo=git://github.com/maoy/inception-chef-repo.git]
[--sequential] [--chef-repo=git://github.com/maoy/inception-chef-repo.git]
[--chef-repo-branch=master]
Note: make sure OpenStack-related environment variables are defined.