From a3077cbb859a9237f9516ed0f073fe00839277c4 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 1 Nov 2010 16:25:56 -0700 Subject: basics to get proxied ajaxterm working with virsh --- bin/nova-ajax-proxy | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100755 bin/nova-ajax-proxy (limited to 'bin') diff --git a/bin/nova-ajax-proxy b/bin/nova-ajax-proxy new file mode 100755 index 000000000..1a0c896ee --- /dev/null +++ b/bin/nova-ajax-proxy @@ -0,0 +1,31 @@ +#!/usr/bin/python +from twisted.internet import reactor +from twisted.web import http +from twisted.web.proxy import Proxy, ProxyRequest +import urlparse, exceptions + +class AjaxProxyRequest(ProxyRequest): + def process(self): + if 'referer' in self.received_headers: + auth_uri = self.received_headers['referer'] + else: + auth_uri = self.uri + + try: + auth_params = urlparse.parse_qs(urlparse.urlparse(auth_uri).query) + parsed_uri = urlparse.urlparse(self.uri) + + self.uri = "http://%s:%s%s?%s"% (auth_params['host'][0], auth_params['port'][0], parsed_uri.path, parsed_uri.query) + + ProxyRequest.process(self) + except (exceptions.KeyError): + pass + +class AjaxProxy(Proxy): + requestFactory = AjaxProxyRequest + +factory = http.HTTPFactory() +factory.protocol = AjaxProxy + +reactor.listenTCP(8000, factory) +reactor.run() -- cgit From 2925ca3ac3010b9a65276ad2cfc8118679827da3 Mon Sep 17 00:00:00 2001 From: masumotok Date: Tue, 7 Dec 2010 19:25:43 +0900 Subject: rev439ベースにライブマイグレーションの機能をマージ このバージョンはEBSなし、CPUフラグのチェックなし MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/nova-manage | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 2 deletions(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index eb7c6b87b..d41ae8600 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -76,6 +76,13 @@ from nova import quota from nova import utils from nova.auth import manager from nova.cloudpipe import pipelib +#added by masumotok +from nova import rpc +# added by masumotok +from nova.api.ec2 import cloud +# added by masumotok +from nova.compute import power_state + FLAGS = flags.FLAGS @@ -424,6 +431,116 @@ class NetworkCommands(object): int(network_size), int(vlan_start), int(vpn_start)) +# this class is added by masumotok +class InstanceCommands(object): + """Class for mangaging VM instances.""" + + def live_migration(self, ec2_id, dest): + """live_migration""" + + logging.basicConfig() + ctxt = context.get_admin_context() + + if 'nova.network.manager.VlanManager' != FLAGS.network_manager : + msg = 'Only nova.network.manager.VlanManager is supported now. Sorry!' + raise Exception(msg) + + # 1. whether destination host exists + host_ref = db.host_get_by_name(ctxt, dest) + + # 2. whether instance exists and running + # try-catch clause is necessary because only internal_id is shown + # when NotFound exception occurs. it isnot understandable to admins. + try : + internal_id = cloud.ec2_id_to_internal_id(ec2_id) + instance_ref = db.instance_get_by_internal_id(ctxt, internal_id) + except exception.NotFound : + print 'Not found instance_id(%s (internal_id:%s))' % ( ec2_id, internal_id) + raise + + if power_state.RUNNING != instance_ref['state'] or \ + 'running' != instance_ref['state_description']: + print 'Instance(%s) is not running' % ec2_id + sys.exit(1) + + # 3. the host where instance is running and dst host is not same + if dest == instance_ref['host'] : + print '%s is where %s is running now. choose different host.' \ + % (dest, ec2_id) + sys.exit(2) + + # 4. live migration + rpc.cast(ctxt, + FLAGS.scheduler_topic, + { "method": "live_migration", + "args": {"ec2_id": ec2_id, + "dest":dest}}) + + print 'Finished all procedure. check instance are migrated successfully' + print 'chech status by using euca-describe-instances.' + + +# this class is created by masumotok +class HostCommands(object): + """Class for mangaging host(physical nodes).""" + + + def list(self): + """describe host list.""" + + # to supress msg: No handlers could be found for logger "amqplib" + logging.basicConfig() + + host_refs = db.host_get_all(context.get_admin_context()) + for host_ref in host_refs: + print host_ref['name'] + + def show(self, host): + """describe cpu/memory/hdd info for host.""" + + # to supress msg: No handlers could be found for logger "amqplib" + logging.basicConfig() + + result = rpc.call(context.get_admin_context(), + FLAGS.scheduler_topic, + {"method": "show_host_resource", + "args": {"host": host}}) + + # checing result msg format is necessary, that will have done + # when this feture is included in API. + if dict != type(result): + print 'Unexpected error occurs' + elif not result['ret'] : + print '%s' % result['msg'] + else : + cpu = result['phy_resource']['cpu'] + mem = result['phy_resource']['memory_mb'] + hdd = result['phy_resource']['hdd_gb'] + + print 'HOST\t\tPROJECT\t\tcpu\tmem(mb)\tdisk(gb)' + print '%s\t\t\t%s\t%s\t%s' % ( host,cpu, mem, hdd) + for p_id, val in result['usage'].items() : + print '%s\t%s\t\t%s\t%s\t%s' % ( host, + p_id, + val['cpu'], + val['memory_mb'], + val['hdd_gb']) + + def has_keys(self, dic, keys): + not_found = [ key for key in keys if not dict.has_key(key) ] + return ( (0 == len(not_found)), not_found ) + + + +# modified by masumotok +#CATEGORIES = [ +# ('user', UserCommands), +# ('project', ProjectCommands), +# ('role', RoleCommands), +# ('shell', ShellCommands), +# ('vpn', VpnCommands), +# ('floating', FloatingIpCommands), +# ('network', NetworkCommands)] CATEGORIES = [ ('user', UserCommands), ('project', ProjectCommands), @@ -431,8 +548,9 @@ CATEGORIES = [ ('shell', ShellCommands), ('vpn', VpnCommands), ('floating', FloatingIpCommands), - ('network', NetworkCommands)] - + ('network', NetworkCommands), + ('instance', InstanceCommands), + ('host',HostCommands)] def lazy_match(name, key_value_tuples): """Finds all objects that have a key that case insensitively contains -- cgit From 4809c1bf82130f969614a8f0458636a462b81a88 Mon Sep 17 00:00:00 2001 From: masumotok Date: Thu, 16 Dec 2010 18:20:04 +0900 Subject: Hostテーブルのカラム名を修正 FlatManager, FlatDHCPManagerに対応 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/nova-manage | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index d41ae8600..d1cda72b7 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -441,10 +441,6 @@ class InstanceCommands(object): logging.basicConfig() ctxt = context.get_admin_context() - if 'nova.network.manager.VlanManager' != FLAGS.network_manager : - msg = 'Only nova.network.manager.VlanManager is supported now. Sorry!' - raise Exception(msg) - # 1. whether destination host exists host_ref = db.host_get_by_name(ctxt, dest) @@ -513,18 +509,18 @@ class HostCommands(object): elif not result['ret'] : print '%s' % result['msg'] else : - cpu = result['phy_resource']['cpu'] + cpu = result['phy_resource']['vcpus'] mem = result['phy_resource']['memory_mb'] - hdd = result['phy_resource']['hdd_gb'] + hdd = result['phy_resource']['local_gb'] print 'HOST\t\tPROJECT\t\tcpu\tmem(mb)\tdisk(gb)' print '%s\t\t\t%s\t%s\t%s' % ( host,cpu, mem, hdd) for p_id, val in result['usage'].items() : print '%s\t%s\t\t%s\t%s\t%s' % ( host, p_id, - val['cpu'], + val['vcpus'], val['memory_mb'], - val['hdd_gb']) + val['local_gb']) def has_keys(self, dic, keys): not_found = [ key for key in keys if not dict.has_key(key) ] -- cgit From f98bb2b2dee4a0ff67a6548646a852686092c53f Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 22 Dec 2010 02:19:38 -0800 Subject: connecting ajax proxy to rabbit to allow token based security --- bin/nova-ajax-proxy | 71 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 7 deletions(-) (limited to 'bin') diff --git a/bin/nova-ajax-proxy b/bin/nova-ajax-proxy index 1a0c896ee..cad496b26 100755 --- a/bin/nova-ajax-proxy +++ b/bin/nova-ajax-proxy @@ -1,8 +1,30 @@ #!/usr/bin/python + +import datetime +import os +import sys + +# If ../nova/__init__.py exists, add ../ to Python search path, so that +# it will override what happens to be installed in /usr/(local/)lib/python... +possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), + os.pardir, + os.pardir)) +if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): + sys.path.insert(0, possible_topdir) + +from nova import utils +from nova import flags +from nova import rpc + +import exceptions +import logging +import urlparse + +FLAGS = flags.FLAGS from twisted.internet import reactor +from twisted.internet import task from twisted.web import http from twisted.web.proxy import Proxy, ProxyRequest -import urlparse, exceptions class AjaxProxyRequest(ProxyRequest): def process(self): @@ -20,12 +42,47 @@ class AjaxProxyRequest(ProxyRequest): ProxyRequest.process(self) except (exceptions.KeyError): pass - + class AjaxProxy(Proxy): + tokens = {} requestFactory = AjaxProxyRequest + + def start(self): + conn = rpc.Connection.instance(new=True) + self.consumer = rpc.TopicConsumer( + connection=conn, + topic=FLAGS.ajax_proxy_topic) + self.consumer.register_callback(self) + + task.LoopingCall(self.age).start(1.0) + task.LoopingCall(self.pollq).start(0.1) + + factory = http.HTTPFactory() + factory.protocol = AjaxProxy + + reactor.listenTCP(8000, factory) + reactor.run() + + def age(self): + pass + + def pollq(self): + self.consumer.fetch(auto_ack=True, enable_callbacks=True) -factory = http.HTTPFactory() -factory.protocol = AjaxProxy - -reactor.listenTCP(8000, factory) -reactor.run() + def __call__(self, data, message): + if data['method'] == 'authorize': + AjaxProxy.tokens['token'] = {'args': data['args'], 'born_at': datetime.datetime.now()} + + +if __name__ == '__main__': + utils.default_flagfile() + FLAGS(sys.argv) + + formatter = logging.Formatter('(%(name)s): %(levelname)s %(message)s') + handler = logging.StreamHandler() + handler.setFormatter(formatter) + logging.getLogger().addHandler(handler) + + ajaxproxy = AjaxProxy() + ajaxproxy.start() + -- cgit From 19f389b3dcc89f0115dc6fc1a6ca606338ad866a Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 22 Dec 2010 12:36:37 -0800 Subject: working connection security --- bin/nova-ajax-proxy | 57 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 16 deletions(-) (limited to 'bin') diff --git a/bin/nova-ajax-proxy b/bin/nova-ajax-proxy index cad496b26..76a70d246 100755 --- a/bin/nova-ajax-proxy +++ b/bin/nova-ajax-proxy @@ -1,8 +1,8 @@ #!/usr/bin/python -import datetime import os import sys +import time # If ../nova/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... @@ -12,8 +12,9 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): sys.path.insert(0, possible_topdir) -from nova import utils +from nova import exception from nova import flags +from nova import utils from nova import rpc import exceptions @@ -23,10 +24,13 @@ import urlparse FLAGS = flags.FLAGS from twisted.internet import reactor from twisted.internet import task -from twisted.web import http +from twisted.web import error, http from twisted.web.proxy import Proxy, ProxyRequest + +flags.DEFINE_integer('ajax_console_idle_timeout', 300, + 'Seconds before idle connection destroyed') -class AjaxProxyRequest(ProxyRequest): +class AjaxConsoleProxyRequest(ProxyRequest): def process(self): if 'referer' in self.received_headers: auth_uri = self.received_headers['referer'] @@ -36,42 +40,63 @@ class AjaxProxyRequest(ProxyRequest): try: auth_params = urlparse.parse_qs(urlparse.urlparse(auth_uri).query) parsed_uri = urlparse.urlparse(self.uri) + + auth_info = auth_params['token'][0] + auth_info = AjaxConsoleProxy.tokens[auth_params['token'][0]] + args = auth_info['args'] + auth_info['last_activity_at'] = time.time() + - self.uri = "http://%s:%s%s?%s"% (auth_params['host'][0], auth_params['port'][0], parsed_uri.path, parsed_uri.query) + self.uri = ("http://%s:%s%s?token=%s"% ( + str(args['host']), + str(args['port']), + parsed_uri.path, + str(args['token']))) ProxyRequest.process(self) except (exceptions.KeyError): - pass + raise exception.NotAuthorized("Unauthorized Request") -class AjaxProxy(Proxy): - tokens = {} - requestFactory = AjaxProxyRequest +class AjaxConsoleProxy(Proxy): + #tokens = {} + tokens = {'key': {'args':'','last_activity_at':time.time()}} + requestFactory = AjaxConsoleProxyRequest def start(self): conn = rpc.Connection.instance(new=True) self.consumer = rpc.TopicConsumer( connection=conn, - topic=FLAGS.ajax_proxy_topic) + topic=FLAGS.ajax_console_proxy_topic) self.consumer.register_callback(self) task.LoopingCall(self.age).start(1.0) task.LoopingCall(self.pollq).start(0.1) factory = http.HTTPFactory() - factory.protocol = AjaxProxy + factory.protocol = AjaxConsoleProxy - reactor.listenTCP(8000, factory) + port = urlparse.urlparse(FLAGS.ajax_console_proxy_url).port + reactor.listenTCP(port, factory) reactor.run() def age(self): - pass + now = time.time() + print now + to_delete = [] + for k, v in AjaxConsoleProxy.tokens.items(): + if now - v['last_activity_at'] > FLAGS.ajax_console_idle_timeout: + to_delete.append(k) + + for k in to_delete: + print "del" + del AjaxConsoleProxy.tokens[k] def pollq(self): self.consumer.fetch(auto_ack=True, enable_callbacks=True) def __call__(self, data, message): - if data['method'] == 'authorize': - AjaxProxy.tokens['token'] = {'args': data['args'], 'born_at': datetime.datetime.now()} + if data['method'] == 'authorize_ajax_console': + AjaxConsoleProxy.tokens[data['args']['token']] = {'args': data['args'], 'born_at': time.time()} if __name__ == '__main__': @@ -83,6 +108,6 @@ if __name__ == '__main__': handler.setFormatter(formatter) logging.getLogger().addHandler(handler) - ajaxproxy = AjaxProxy() + ajaxproxy = AjaxConsoleProxy() ajaxproxy.start() -- cgit From 4e9b4c9ce31a7a50d7e38d5e0bd71718d5bb8b95 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 22 Dec 2010 18:52:43 -0800 Subject: minor notes, commit before rewriting proxy with eventlet --- bin/nova-ajax-proxy | 1 - 1 file changed, 1 deletion(-) (limited to 'bin') diff --git a/bin/nova-ajax-proxy b/bin/nova-ajax-proxy index 76a70d246..4948897cc 100755 --- a/bin/nova-ajax-proxy +++ b/bin/nova-ajax-proxy @@ -46,7 +46,6 @@ class AjaxConsoleProxyRequest(ProxyRequest): args = auth_info['args'] auth_info['last_activity_at'] = time.time() - self.uri = ("http://%s:%s%s?token=%s"% ( str(args['host']), str(args['port']), -- cgit From 4364a6e0570794fca841a7e5ecc8cecebf1bae9b Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 22 Dec 2010 23:41:07 -0800 Subject: rewrite proxy to not use twisted --- bin/nova-ajax-proxy | 128 ++++++++++++++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 65 deletions(-) (limited to 'bin') diff --git a/bin/nova-ajax-proxy b/bin/nova-ajax-proxy index 4948897cc..52d7ee3de 100755 --- a/bin/nova-ajax-proxy +++ b/bin/nova-ajax-proxy @@ -12,101 +12,99 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): sys.path.insert(0, possible_topdir) +import webob.dec +import webob.exc + from nova import exception from nova import flags from nova import utils from nova import rpc +from nova import wsgi import exceptions import logging import urlparse FLAGS = flags.FLAGS -from twisted.internet import reactor -from twisted.internet import task -from twisted.web import error, http -from twisted.web.proxy import Proxy, ProxyRequest flags.DEFINE_integer('ajax_console_idle_timeout', 300, 'Seconds before idle connection destroyed') -class AjaxConsoleProxyRequest(ProxyRequest): - def process(self): - if 'referer' in self.received_headers: - auth_uri = self.received_headers['referer'] - else: - auth_uri = self.uri +import eventlet +from eventlet import greenthread +from eventlet.green import urllib2 + +class AjaxConsoleProxy(object): + tokens = {} + def __call__(self, environ, start_response): try: - auth_params = urlparse.parse_qs(urlparse.urlparse(auth_uri).query) - parsed_uri = urlparse.urlparse(self.uri) + req_url = '%s://%s%s?%s' % (environ['wsgi.url_scheme'], environ['HTTP_HOST'], environ['PATH_INFO'], environ['QUERY_STRING']) + if 'HTTP_REFERER' in environ: + auth_url = environ['HTTP_REFERER'] + else: + auth_url = req_url + + auth_params = urlparse.parse_qs(urlparse.urlparse(auth_url).query) + parsed_url = urlparse.urlparse(req_url) - auth_info = auth_params['token'][0] - auth_info = AjaxConsoleProxy.tokens[auth_params['token'][0]] + auth_info = AjaxConsoleProxy.tokens[auth_params['token'][0]] args = auth_info['args'] auth_info['last_activity_at'] = time.time() - self.uri = ("http://%s:%s%s?token=%s"% ( - str(args['host']), - str(args['port']), - parsed_uri.path, - str(args['token']))) + remote_url = ("http://%s:%s%s?token=%s"% ( + str(args['host']), + str(args['port']), + parsed_url.path, + str(args['token']))) - ProxyRequest.process(self) + opener = urllib2.urlopen(remote_url, environ['wsgi.input'].read()) + body = opener.read() + info = opener.info() + + start_response("200 OK", info.dict.items()) + return body except (exceptions.KeyError): - raise exception.NotAuthorized("Unauthorized Request") + start_response("401 NOT AUTHORIZED",[]) + return "Not Authorized" + except Exception: + start_response("500 ERROR",[]) + return "Server Error" + -class AjaxConsoleProxy(Proxy): - #tokens = {} - tokens = {'key': {'args':'','last_activity_at':time.time()}} - requestFactory = AjaxConsoleProxyRequest + def register_listeners(self): + class Callback: + def __call__(self, data, message): + if data['method'] == 'authorize_ajax_console': + AjaxConsoleProxy.tokens[data['args']['token']] = \ + {'args': data['args'], 'last_activity_at': time.time()} - def start(self): conn = rpc.Connection.instance(new=True) - self.consumer = rpc.TopicConsumer( + consumer = rpc.TopicConsumer( connection=conn, topic=FLAGS.ajax_console_proxy_topic) - self.consumer.register_callback(self) - - task.LoopingCall(self.age).start(1.0) - task.LoopingCall(self.pollq).start(0.1) - - factory = http.HTTPFactory() - factory.protocol = AjaxConsoleProxy - - port = urlparse.urlparse(FLAGS.ajax_console_proxy_url).port - reactor.listenTCP(port, factory) - reactor.run() - - def age(self): - now = time.time() - print now - to_delete = [] - for k, v in AjaxConsoleProxy.tokens.items(): - if now - v['last_activity_at'] > FLAGS.ajax_console_idle_timeout: - to_delete.append(k) - - for k in to_delete: - print "del" - del AjaxConsoleProxy.tokens[k] - - def pollq(self): - self.consumer.fetch(auto_ack=True, enable_callbacks=True) - - def __call__(self, data, message): - if data['method'] == 'authorize_ajax_console': - AjaxConsoleProxy.tokens[data['args']['token']] = {'args': data['args'], 'born_at': time.time()} + consumer.register_callback(Callback()) + + def delete_expired_tokens(): + now = time.time() + to_delete = [] + for k, v in AjaxConsoleProxy.tokens.items(): + if now - v['last_activity_at'] > FLAGS.ajax_console_idle_timeout: + to_delete.append(k) + for k in to_delete: + del AjaxConsoleProxy.tokens[k] + + utils.LoopingCall(consumer.fetch, auto_ack=True, + enable_callbacks=True).start(0.1) + utils.LoopingCall(delete_expired_tokens).start(1) if __name__ == '__main__': utils.default_flagfile() FLAGS(sys.argv) + server = wsgi.Server() + acp = AjaxConsoleProxy() + acp.register_listeners() + server.start(acp, FLAGS.ajax_console_proxy_port, host='0.0.0.0') + server.wait() - formatter = logging.Formatter('(%(name)s): %(levelname)s %(message)s') - handler = logging.StreamHandler() - handler.setFormatter(formatter) - logging.getLogger().addHandler(handler) - - ajaxproxy = AjaxConsoleProxy() - ajaxproxy.start() - -- cgit From 237326dd6b5905a18fc7ba740457ceb52164ab59 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 22 Dec 2010 23:46:21 -0800 Subject: some cleanup --- bin/nova-ajax-proxy | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'bin') diff --git a/bin/nova-ajax-proxy b/bin/nova-ajax-proxy index 52d7ee3de..df73b0adf 100755 --- a/bin/nova-ajax-proxy +++ b/bin/nova-ajax-proxy @@ -1,8 +1,15 @@ #!/usr/bin/python +from eventlet import greenthread +from eventlet.green import urllib2 + +import exceptions +import logging import os import sys import time +import urlparse + # If ../nova/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... @@ -12,36 +19,28 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): sys.path.insert(0, possible_topdir) -import webob.dec -import webob.exc - -from nova import exception from nova import flags from nova import utils from nova import rpc from nova import wsgi -import exceptions -import logging -import urlparse - FLAGS = flags.FLAGS flags.DEFINE_integer('ajax_console_idle_timeout', 300, 'Seconds before idle connection destroyed') -import eventlet -from eventlet import greenthread -from eventlet.green import urllib2 class AjaxConsoleProxy(object): tokens = {} - def __call__(self, environ, start_response): + def __call__(self, env, start_response): try: - req_url = '%s://%s%s?%s' % (environ['wsgi.url_scheme'], environ['HTTP_HOST'], environ['PATH_INFO'], environ['QUERY_STRING']) - if 'HTTP_REFERER' in environ: - auth_url = environ['HTTP_REFERER'] + req_url = '%s://%s%s?%s' % (env['wsgi.url_scheme'], + env['HTTP_HOST'], + env['PATH_INFO'], + env['QUERY_STRING']) + if 'HTTP_REFERER' in env: + auth_url = env['HTTP_REFERER'] else: auth_url = req_url @@ -50,7 +49,7 @@ class AjaxConsoleProxy(object): auth_info = AjaxConsoleProxy.tokens[auth_params['token'][0]] args = auth_info['args'] - auth_info['last_activity_at'] = time.time() + auth_info['last_activity'] = time.time() remote_url = ("http://%s:%s%s?token=%s"% ( str(args['host']), @@ -58,7 +57,7 @@ class AjaxConsoleProxy(object): parsed_url.path, str(args['token']))) - opener = urllib2.urlopen(remote_url, environ['wsgi.input'].read()) + opener = urllib2.urlopen(remote_url, env['wsgi.input'].read()) body = opener.read() info = opener.info() @@ -77,7 +76,7 @@ class AjaxConsoleProxy(object): def __call__(self, data, message): if data['method'] == 'authorize_ajax_console': AjaxConsoleProxy.tokens[data['args']['token']] = \ - {'args': data['args'], 'last_activity_at': time.time()} + {'args': data['args'], 'last_activity': time.time()} conn = rpc.Connection.instance(new=True) consumer = rpc.TopicConsumer( @@ -89,7 +88,7 @@ class AjaxConsoleProxy(object): now = time.time() to_delete = [] for k, v in AjaxConsoleProxy.tokens.items(): - if now - v['last_activity_at'] > FLAGS.ajax_console_idle_timeout: + if now - v['last_activity'] > FLAGS.ajax_console_idle_timeout: to_delete.append(k) for k in to_delete: -- cgit From e6a01c663bbcd5fc5244c48b97ef0bef4ce524ea Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 22 Dec 2010 23:47:46 -0800 Subject: add in license --- bin/nova-ajax-proxy | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/nova-ajax-proxy b/bin/nova-ajax-proxy index df73b0adf..3adc1018c 100755 --- a/bin/nova-ajax-proxy +++ b/bin/nova-ajax-proxy @@ -1,4 +1,25 @@ -#!/usr/bin/python +#!/usr/bin/env python +# pylint: disable-msg=C0103 +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Ajax Console Proxy Server""" + from eventlet import greenthread from eventlet.green import urllib2 -- cgit From 86b9e564fec24423485b5087e41584abd0de1da0 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 22 Dec 2010 23:49:10 -0800 Subject: more tweaks --- bin/nova-ajax-proxy | 3 --- 1 file changed, 3 deletions(-) (limited to 'bin') diff --git a/bin/nova-ajax-proxy b/bin/nova-ajax-proxy index 3adc1018c..bc828c5b1 100755 --- a/bin/nova-ajax-proxy +++ b/bin/nova-ajax-proxy @@ -20,7 +20,6 @@ """Ajax Console Proxy Server""" - from eventlet import greenthread from eventlet.green import urllib2 @@ -31,7 +30,6 @@ import sys import time import urlparse - # If ../nova/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), @@ -91,7 +89,6 @@ class AjaxConsoleProxy(object): start_response("500 ERROR",[]) return "Server Error" - def register_listeners(self): class Callback: def __call__(self, data, message): -- cgit From 50fe4b93ce2a015c31286d2b2de64a0128761086 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 23 Dec 2010 01:26:03 -0800 Subject: pep8 fixes --- bin/nova-ajax-proxy | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'bin') diff --git a/bin/nova-ajax-proxy b/bin/nova-ajax-proxy index bc828c5b1..53b779711 100755 --- a/bin/nova-ajax-proxy +++ b/bin/nova-ajax-proxy @@ -21,7 +21,7 @@ """Ajax Console Proxy Server""" from eventlet import greenthread -from eventlet.green import urllib2 +from eventlet.green import urllib2 import exceptions import logging @@ -45,9 +45,9 @@ from nova import wsgi FLAGS = flags.FLAGS -flags.DEFINE_integer('ajax_console_idle_timeout', 300, +flags.DEFINE_integer('ajax_console_idle_timeout', 300, 'Seconds before idle connection destroyed') - + class AjaxConsoleProxy(object): tokens = {} @@ -67,10 +67,10 @@ class AjaxConsoleProxy(object): parsed_url = urlparse.urlparse(req_url) auth_info = AjaxConsoleProxy.tokens[auth_params['token'][0]] - args = auth_info['args'] - auth_info['last_activity'] = time.time() + args = auth_info['args'] + auth_info['last_activity'] = time.time() - remote_url = ("http://%s:%s%s?token=%s"% ( + remote_url = ("http://%s:%s%s?token=%s" % ( str(args['host']), str(args['port']), parsed_url.path, @@ -83,10 +83,10 @@ class AjaxConsoleProxy(object): start_response("200 OK", info.dict.items()) return body except (exceptions.KeyError): - start_response("401 NOT AUTHORIZED",[]) + start_response("401 NOT AUTHORIZED", []) return "Not Authorized" except Exception: - start_response("500 ERROR",[]) + start_response("500 ERROR", []) return "Server Error" def register_listeners(self): @@ -112,7 +112,7 @@ class AjaxConsoleProxy(object): for k in to_delete: del AjaxConsoleProxy.tokens[k] - utils.LoopingCall(consumer.fetch, auto_ack=True, + utils.LoopingCall(consumer.fetch, auto_ack=True, enable_callbacks=True).start(0.1) utils.LoopingCall(delete_expired_tokens).start(1) @@ -124,4 +124,3 @@ if __name__ == '__main__': acp.register_listeners() server.start(acp, FLAGS.ajax_console_proxy_port, host='0.0.0.0') server.wait() - -- cgit From e4c1fa91e0245dc6f673c5ac8880a99bd3d0dea1 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 23 Dec 2010 01:32:15 -0800 Subject: better bin name, and pep8 --- bin/nova-ajax-console-proxy | 126 ++++++++++++++++++++++++++++++++++++++++++++ bin/nova-ajax-proxy | 126 -------------------------------------------- 2 files changed, 126 insertions(+), 126 deletions(-) create mode 100755 bin/nova-ajax-console-proxy delete mode 100755 bin/nova-ajax-proxy (limited to 'bin') diff --git a/bin/nova-ajax-console-proxy b/bin/nova-ajax-console-proxy new file mode 100755 index 000000000..53b779711 --- /dev/null +++ b/bin/nova-ajax-console-proxy @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# pylint: disable-msg=C0103 +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Ajax Console Proxy Server""" + +from eventlet import greenthread +from eventlet.green import urllib2 + +import exceptions +import logging +import os +import sys +import time +import urlparse + +# If ../nova/__init__.py exists, add ../ to Python search path, so that +# it will override what happens to be installed in /usr/(local/)lib/python... +possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), + os.pardir, + os.pardir)) +if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): + sys.path.insert(0, possible_topdir) + +from nova import flags +from nova import utils +from nova import rpc +from nova import wsgi + +FLAGS = flags.FLAGS + +flags.DEFINE_integer('ajax_console_idle_timeout', 300, + 'Seconds before idle connection destroyed') + + +class AjaxConsoleProxy(object): + tokens = {} + + def __call__(self, env, start_response): + try: + req_url = '%s://%s%s?%s' % (env['wsgi.url_scheme'], + env['HTTP_HOST'], + env['PATH_INFO'], + env['QUERY_STRING']) + if 'HTTP_REFERER' in env: + auth_url = env['HTTP_REFERER'] + else: + auth_url = req_url + + auth_params = urlparse.parse_qs(urlparse.urlparse(auth_url).query) + parsed_url = urlparse.urlparse(req_url) + + auth_info = AjaxConsoleProxy.tokens[auth_params['token'][0]] + args = auth_info['args'] + auth_info['last_activity'] = time.time() + + remote_url = ("http://%s:%s%s?token=%s" % ( + str(args['host']), + str(args['port']), + parsed_url.path, + str(args['token']))) + + opener = urllib2.urlopen(remote_url, env['wsgi.input'].read()) + body = opener.read() + info = opener.info() + + start_response("200 OK", info.dict.items()) + return body + except (exceptions.KeyError): + start_response("401 NOT AUTHORIZED", []) + return "Not Authorized" + except Exception: + start_response("500 ERROR", []) + return "Server Error" + + def register_listeners(self): + class Callback: + def __call__(self, data, message): + if data['method'] == 'authorize_ajax_console': + AjaxConsoleProxy.tokens[data['args']['token']] = \ + {'args': data['args'], 'last_activity': time.time()} + + conn = rpc.Connection.instance(new=True) + consumer = rpc.TopicConsumer( + connection=conn, + topic=FLAGS.ajax_console_proxy_topic) + consumer.register_callback(Callback()) + + def delete_expired_tokens(): + now = time.time() + to_delete = [] + for k, v in AjaxConsoleProxy.tokens.items(): + if now - v['last_activity'] > FLAGS.ajax_console_idle_timeout: + to_delete.append(k) + + for k in to_delete: + del AjaxConsoleProxy.tokens[k] + + utils.LoopingCall(consumer.fetch, auto_ack=True, + enable_callbacks=True).start(0.1) + utils.LoopingCall(delete_expired_tokens).start(1) + +if __name__ == '__main__': + utils.default_flagfile() + FLAGS(sys.argv) + server = wsgi.Server() + acp = AjaxConsoleProxy() + acp.register_listeners() + server.start(acp, FLAGS.ajax_console_proxy_port, host='0.0.0.0') + server.wait() diff --git a/bin/nova-ajax-proxy b/bin/nova-ajax-proxy deleted file mode 100755 index 53b779711..000000000 --- a/bin/nova-ajax-proxy +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env python -# pylint: disable-msg=C0103 -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Ajax Console Proxy Server""" - -from eventlet import greenthread -from eventlet.green import urllib2 - -import exceptions -import logging -import os -import sys -import time -import urlparse - -# If ../nova/__init__.py exists, add ../ to Python search path, so that -# it will override what happens to be installed in /usr/(local/)lib/python... -possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), - os.pardir, - os.pardir)) -if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): - sys.path.insert(0, possible_topdir) - -from nova import flags -from nova import utils -from nova import rpc -from nova import wsgi - -FLAGS = flags.FLAGS - -flags.DEFINE_integer('ajax_console_idle_timeout', 300, - 'Seconds before idle connection destroyed') - - -class AjaxConsoleProxy(object): - tokens = {} - - def __call__(self, env, start_response): - try: - req_url = '%s://%s%s?%s' % (env['wsgi.url_scheme'], - env['HTTP_HOST'], - env['PATH_INFO'], - env['QUERY_STRING']) - if 'HTTP_REFERER' in env: - auth_url = env['HTTP_REFERER'] - else: - auth_url = req_url - - auth_params = urlparse.parse_qs(urlparse.urlparse(auth_url).query) - parsed_url = urlparse.urlparse(req_url) - - auth_info = AjaxConsoleProxy.tokens[auth_params['token'][0]] - args = auth_info['args'] - auth_info['last_activity'] = time.time() - - remote_url = ("http://%s:%s%s?token=%s" % ( - str(args['host']), - str(args['port']), - parsed_url.path, - str(args['token']))) - - opener = urllib2.urlopen(remote_url, env['wsgi.input'].read()) - body = opener.read() - info = opener.info() - - start_response("200 OK", info.dict.items()) - return body - except (exceptions.KeyError): - start_response("401 NOT AUTHORIZED", []) - return "Not Authorized" - except Exception: - start_response("500 ERROR", []) - return "Server Error" - - def register_listeners(self): - class Callback: - def __call__(self, data, message): - if data['method'] == 'authorize_ajax_console': - AjaxConsoleProxy.tokens[data['args']['token']] = \ - {'args': data['args'], 'last_activity': time.time()} - - conn = rpc.Connection.instance(new=True) - consumer = rpc.TopicConsumer( - connection=conn, - topic=FLAGS.ajax_console_proxy_topic) - consumer.register_callback(Callback()) - - def delete_expired_tokens(): - now = time.time() - to_delete = [] - for k, v in AjaxConsoleProxy.tokens.items(): - if now - v['last_activity'] > FLAGS.ajax_console_idle_timeout: - to_delete.append(k) - - for k in to_delete: - del AjaxConsoleProxy.tokens[k] - - utils.LoopingCall(consumer.fetch, auto_ack=True, - enable_callbacks=True).start(0.1) - utils.LoopingCall(delete_expired_tokens).start(1) - -if __name__ == '__main__': - utils.default_flagfile() - FLAGS(sys.argv) - server = wsgi.Server() - acp = AjaxConsoleProxy() - acp.register_listeners() - server.start(acp, FLAGS.ajax_console_proxy_port, host='0.0.0.0') - server.wait() -- cgit From f983884dd262f46907f80a04121d957347881240 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Dec 2010 15:09:05 +0900 Subject: nova.compute.managerがこれまでの修正でデグレしていたので修正 CPUID, その他のチェックルーチンをnova.scheduler.manager.live_migrationに追加 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/nova-manage | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index d1cda72b7..d6aa29679 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -456,24 +456,25 @@ class InstanceCommands(object): if power_state.RUNNING != instance_ref['state'] or \ 'running' != instance_ref['state_description']: - print 'Instance(%s) is not running' % ec2_id - sys.exit(1) + raise exception.Invalid('Instance(%s) is not running' % ec2_id) # 3. the host where instance is running and dst host is not same if dest == instance_ref['host'] : - print '%s is where %s is running now. choose different host.' \ - % (dest, ec2_id) - sys.exit(2) + msg = '%s is where %s is running now. choose other host.' % (dest, ec2_id) + raise exception.Invalid(msg) # 4. live migration - rpc.cast(ctxt, - FLAGS.scheduler_topic, - { "method": "live_migration", - "args": {"ec2_id": ec2_id, - "dest":dest}}) + ret = rpc.call(ctxt, + FLAGS.scheduler_topic, + { "method": "live_migration", + "args": {"ec2_id": ec2_id, + "dest":dest}}) + + if None != ret : + raise ret print 'Finished all procedure. check instance are migrated successfully' - print 'chech status by using euca-describe-instances.' + print 'check status by using euca-describe-instances.' # this class is created by masumotok -- cgit From c5c58cb20def79401a374f863983a343139b53f3 Mon Sep 17 00:00:00 2001 From: "NTT PF Lab." Date: Fri, 24 Dec 2010 20:38:49 +0900 Subject: Support IPv6 --- bin/nova-manage | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index 0c1b621ed..e0f6f9323 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -87,7 +87,7 @@ flags.DECLARE('num_networks', 'nova.network.manager') flags.DECLARE('network_size', 'nova.network.manager') flags.DECLARE('vlan_start', 'nova.network.manager') flags.DECLARE('vpn_start', 'nova.network.manager') - +flags.DECLARE('fixed_range_v6', 'nova.network.manager') class VpnCommands(object): """Class for managing VPNs.""" @@ -411,11 +411,11 @@ class NetworkCommands(object): """Class for managing networks.""" def create(self, fixed_range=None, num_networks=None, - network_size=None, vlan_start=None, vpn_start=None): + network_size=None, vlan_start=None, vpn_start=None,fixed_range_v6=None): """Creates fixed ips for host by range arguments: [fixed_range=FLAG], [num_networks=FLAG], [network_size=FLAG], [vlan_start=FLAG], - [vpn_start=FLAG]""" + [vpn_start=FLAG],[fixed_range_v6=FLAG]""" if not fixed_range: fixed_range = FLAGS.fixed_range if not num_networks: @@ -426,11 +426,15 @@ class NetworkCommands(object): vlan_start = FLAGS.vlan_start if not vpn_start: vpn_start = FLAGS.vpn_start + if not fixed_range_v6: + fixed_range_v6 = FLAGS.fixed_range_v6 net_manager = utils.import_object(FLAGS.network_manager) net_manager.create_networks(context.get_admin_context(), fixed_range, int(num_networks), int(network_size), int(vlan_start), - int(vpn_start)) + int(vpn_start),fixed_range_v6) + + CATEGORIES = [ ('user', UserCommands), -- cgit From 8e1b74aa1c5a2f9113473eedc8e35b38b41445ea Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Mon, 27 Dec 2010 15:15:24 -0800 Subject: Added stack command-line tool --- bin/nova-easy-api | 61 +++++++++++++++++++++++ bin/stack | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100755 bin/nova-easy-api create mode 100755 bin/stack (limited to 'bin') diff --git a/bin/nova-easy-api b/bin/nova-easy-api new file mode 100755 index 000000000..e8e86b4fb --- /dev/null +++ b/bin/nova-easy-api @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# pylint: disable-msg=C0103 +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Starter script for Nova Easy API.""" + +import gettext +import os +import sys + +# If ../nova/__init__.py exists, add ../ to Python search path, so that +# it will override what happens to be installed in /usr/(local/)lib/python... +possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), + os.pardir, + os.pardir)) +if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): + sys.path.insert(0, possible_topdir) + +gettext.install('nova', unicode=1) + +from nova import flags +from nova import utils +from nova import wsgi +from nova.api import easy +from nova.compute import api as compute_api + + +FLAGS = flags.FLAGS +flags.DEFINE_integer('easy_port', 8001, 'Easy API port') +flags.DEFINE_string('easy_host', '0.0.0.0', 'Easy API host') + +if __name__ == '__main__': + utils.default_flagfile() + FLAGS(sys.argv) + + easy.register_service('compute', compute_api.ComputeAPI()) + easy.register_service('reflect', easy.Reflection()) + router = easy.SundayMorning() + with_json = easy.JsonParamsMiddleware(router) + with_req = easy.ReqParamsMiddleware(with_json) + with_auth = easy.DelegatedAuthMiddleware(with_req) + + server = wsgi.Server() + server.start(with_auth, FLAGS.easy_port, host=FLAGS.easy_host) + server.wait() diff --git a/bin/stack b/bin/stack new file mode 100755 index 000000000..284dbf4fc --- /dev/null +++ b/bin/stack @@ -0,0 +1,145 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""CLI for the Easy API.""" + +import eventlet +eventlet.monkey_patch() + +import os +import pprint +import sys +import textwrap +import urllib +import urllib2 + +# If ../nova/__init__.py exists, add ../ to Python search path, so that +# it will override what happens to be installed in /usr/(local/)lib/python... +possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), + os.pardir, + os.pardir)) +if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): + sys.path.insert(0, possible_topdir) + +import gflags +from nova import utils + + +FLAGS = gflags.FLAGS +gflags.DEFINE_string('host', '127.0.0.1', 'Easy API host') +gflags.DEFINE_integer('port', 8001, 'Easy API host') +gflags.DEFINE_string('user', 'user1', 'Easy API username') +gflags.DEFINE_string('project', 'proj1', 'Easy API project') + + +USAGE = """usage: stack [options] [arg1=value arg2=value] + + `stack help` should output the list of available controllers + `stack ` should output the available methods for that controller + `stack help ` should do the same + `stack help ` should output info for a method +""" + + +def format_help(d): + """Format help text, keys are labels and values are descriptions.""" + indent = max([len(k) for k in d]) + out = [] + for k, v in d.iteritems(): + t = textwrap.TextWrapper(initial_indent=' %s ' % k.ljust(indent), + subsequent_indent=' ' * (indent + 6)) + out.extend(t.wrap(v)) + return out + + +def help_all(): + rv = do_request('reflect', 'get_controllers') + out = format_help(rv) + return (USAGE + str(FLAGS.MainModuleHelp()) + + '\n\nAvailable controllers:\n' + + '\n'.join(out) + '\n') + + +def help_controller(controller): + rv = do_request('reflect', 'get_methods') + methods = dict([(k.split('/')[2], v) for k, v in rv.iteritems() + if k.startswith('/%s' % controller)]) + return ('Available methods for %s:\n' % controller + + '\n'.join(format_help(methods))) + + +def help_method(controller, method): + rv = do_request('reflect', + 'get_method_info', + {'method': '/%s/%s' % (controller, method)}) + + sig = '%s(%s):' % (method, ', '.join(['='.join(x) for x in rv['args']])) + out = textwrap.wrap(sig, subsequent_indent=' ' * len('%s(' % method)) + out.append('\n' + rv['doc']) + return '\n'.join(out) + + +def do_request(controller, method, params=None): + if params: + data = urllib.urlencode(params) + else: + data = None + + url = 'http://%s:%s/%s/%s' % (FLAGS.host, FLAGS.port, controller, method) + headers = {'X-OpenStack-User': FLAGS.user, + 'X-OpenStack-Project': FLAGS.project} + + req = urllib2.Request(url, data, headers) + resp = urllib2.urlopen(req) + return utils.loads(resp.read()) + + +if __name__ == '__main__': + args = FLAGS(sys.argv) + + cmd = args.pop(0) + if not args: + print help_all() + sys.exit() + + first = args.pop(0) + if first == 'help': + action = help_all + params = [] + if args: + params.append(args.pop(0)) + action = help_controller + if args: + params.append(args.pop(0)) + action = help_method + print action(*params) + sys.exit(0) + + controller = first + if not args: + print help_controller(controller) + sys.exit() + + method = args.pop(0) + params = {} + for x in args: + key, value = args.split('=', 1) + params[key] = value + + pprint.pprint(do_request(controller, method, params)) -- cgit From c7305af78049f94dedcbb55480b91a3c6d843b9f Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Tue, 4 Jan 2011 00:23:35 -0500 Subject: Apply logging changes as a giant patch to work around the cloudpipe delete + add issue in the original patch. --- bin/nova-dhcpbridge | 20 +++--- bin/nova-instancemonitor | 7 ++- bin/nova-logspool | 156 +++++++++++++++++++++++++++++++++++++++++++++++ bin/nova-manage | 19 ++++-- bin/nova-spoolsentry | 97 +++++++++++++++++++++++++++++ 5 files changed, 285 insertions(+), 14 deletions(-) create mode 100644 bin/nova-logspool create mode 100644 bin/nova-spoolsentry (limited to 'bin') diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index 828aba3d1..cecc1c80c 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -22,7 +22,6 @@ Handle lease database updates from DHCP servers. """ import gettext -import logging import os import sys @@ -39,6 +38,7 @@ gettext.install('nova', unicode=1) from nova import context from nova import db from nova import flags +from nova import log as logging from nova import rpc from nova import utils from nova.network import linux_net @@ -50,10 +50,15 @@ flags.DECLARE('num_networks', 'nova.network.manager') flags.DECLARE('update_dhcp_on_disassociate', 'nova.network.manager') +LOG = logging.getLogger('nova-dhcpbridge') +if FLAGS.verbose: + LOG.setLevel(logging.DEBUG) + + def add_lease(mac, ip_address, _hostname, _interface): """Set the IP that was assigned by the DHCP server.""" if FLAGS.fake_rabbit: - logging.debug("leasing ip") + LOG.debug("leasing ip") network_manager = utils.import_object(FLAGS.network_manager) network_manager.lease_fixed_ip(context.get_admin_context(), mac, @@ -68,14 +73,14 @@ def add_lease(mac, ip_address, _hostname, _interface): def old_lease(mac, ip_address, hostname, interface): """Update just as add lease.""" - logging.debug("Adopted old lease or got a change of mac/hostname") + LOG.debug("Adopted old lease or got a change of mac/hostname") add_lease(mac, ip_address, hostname, interface) def del_lease(mac, ip_address, _hostname, _interface): """Called when a lease expires.""" if FLAGS.fake_rabbit: - logging.debug("releasing ip") + LOG.debug("releasing ip") network_manager = utils.import_object(FLAGS.network_manager) network_manager.release_fixed_ip(context.get_admin_context(), mac, @@ -100,6 +105,7 @@ def main(): flagfile = os.environ.get('FLAGFILE', FLAGS.dhcpbridge_flagfile) utils.default_flagfile(flagfile) argv = FLAGS(sys.argv) + logging.basicConfig() interface = os.environ.get('DNSMASQ_INTERFACE', 'br0') if int(os.environ.get('TESTING', '0')): FLAGS.fake_rabbit = True @@ -117,9 +123,9 @@ def main(): mac = argv[2] ip = argv[3] hostname = argv[4] - logging.debug("Called %s for mac %s with ip %s and " - "hostname %s on interface %s", - action, mac, ip, hostname, interface) + LOG.debug("Called %s for mac %s with ip %s and " + "hostname %s on interface %s", + action, mac, ip, hostname, interface) globals()[action + '_lease'](mac, ip, hostname, interface) else: print init_leases(interface) diff --git a/bin/nova-instancemonitor b/bin/nova-instancemonitor index 5dac3ffe6..17f573b9d 100755 --- a/bin/nova-instancemonitor +++ b/bin/nova-instancemonitor @@ -23,7 +23,6 @@ import gettext import os -import logging import sys from twisted.application import service @@ -37,19 +36,23 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) +from nova import log as logging from nova import utils from nova import twistd from nova.compute import monitor +# TODO(todd): shouldn't this be done with flags? And what about verbose? logging.getLogger('boto').setLevel(logging.WARN) +LOG = logging.getLogger('nova-instancemonitor') + if __name__ == '__main__': utils.default_flagfile() twistd.serve(__file__) if __name__ == '__builtin__': - logging.warn('Starting instance monitor') + LOG.warn(_('Starting instance monitor')) # pylint: disable-msg=C0103 monitor = monitor.InstanceMonitor() diff --git a/bin/nova-logspool b/bin/nova-logspool new file mode 100644 index 000000000..d5aef4756 --- /dev/null +++ b/bin/nova-logspool @@ -0,0 +1,156 @@ +#!/usr/bin/env python + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Tools for working with logs generated by nova components +""" + + +import json +import os +import re +import sys + + +class Request(object): + + def __init__(self): + self.time = "" + self.host = "" + self.logger = "" + self.message = "" + self.trace = "" + self.env = "" + self.request_id = "" + + def add_error_line(self, error_line): + self.time = " ".join(error_line.split(" ")[:3]) + self.host = error_line.split(" ")[3] + self.logger = error_line.split("(")[1].split(" ")[0] + self.request_id = error_line.split("[")[1].split(" ")[0] + error_lines = error_line.split("#012") + self.message = self.clean_log_line(error_lines.pop(0)) + self.trace = "\n".join([self.clean_trace(l) for l in error_lines]) + + def add_environment_line(self, env_line): + self.env = self.clean_env_line(env_line) + + def clean_log_line(self, line): + """Remove log format for time, level, etc: split after context""" + return line.split('] ')[-1] + + def clean_env_line(self, line): + """Also has an 'Environment: ' string in the message""" + return re.sub(r'^Environment: ', '', self.clean_log_line(line)) + + def clean_trace(self, line): + """trace has a different format, so split on TRACE:""" + return line.split('TRACE: ')[-1] + + def to_dict(self): + return {'traceback': self.trace, 'message': self.message, + 'host': self.host, 'env': self.env, 'logger': self.logger, + 'request_id': self.request_id} + +class LogReader(object): + def __init__(self, filename): + self.filename = filename + self._errors = {} + + def process(self, spooldir): + with open(self.filename) as f: + line = f.readline() + while len(line) > 0: + parts = line.split(" ") + level = (len(parts) < 6) or parts[5] + if level == 'ERROR': + self.handle_logged_error(line) + elif level == '[-]' and self.last_error: + # twisted stack trace line + clean_line = " ".join(line.split(" ")[6:]) + self.last_error.trace = self.last_error.trace + clean_line + else: + self.last_error = None + line = f.readline() + self.update_spool(spooldir) + + def handle_logged_error(self, line): + request_id = re.search(r' \[([A-Z0-9\-/]+)', line) + if not request_id: + raise Exception("Unable to parse request id from %s" % line) + request_id = request_id.group(1) + data = self._errors.get(request_id, Request()) + if self.is_env_line(line): + data.add_environment_line(line) + elif self.is_error_line(line): + data.add_error_line(line) + else: + # possibly error from twsited + data.add_error_line(line) + self.last_error = data + self._errors[request_id] = data + + def is_env_line(self, line): + return re.search('Environment: ', line) + + def is_error_line(self, line): + return re.search('raised', line) + + def update_spool(self, directory): + processed_dir = "%s/processed" % directory + self._ensure_dir_exists(processed_dir) + for rid, value in self._errors.iteritems(): + if not self.has_been_processed(processed_dir, rid): + with open("%s/%s" % (directory, rid), "w") as spool: + spool.write(json.dumps(value.to_dict())) + self.flush_old_processed_spool(processed_dir) + + def _ensure_dir_exists(self, d): + mkdir = False + try: + os.stat(d) + except: + mkdir = True + if mkdir: + os.mkdir(d) + + def has_been_processed(self, processed_dir, rid): + rv = False + try: + os.stat("%s/%s" % (processed_dir, rid)) + rv = True + except: + pass + return rv + + def flush_old_processed_spool(self, processed_dir): + keys = self._errors.keys() + procs = os.listdir(processed_dir) + for p in procs: + if p not in keys: + # log has rotated and the old error won't be seen again + os.unlink("%s/%s" % (processed_dir, p)) + +if __name__ == '__main__': + filename = '/var/log/nova.log' + spooldir = '/var/spool/nova' + if len(sys.argv) > 1: + filename = sys.argv[1] + if len(sys.argv) > 2: + spooldir = sys.argv[2] + LogReader(filename).process(spooldir) diff --git a/bin/nova-manage b/bin/nova-manage index 3416c1a52..169ab5f62 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -55,8 +55,8 @@ import datetime import gettext -import logging import os +import re import sys import time @@ -77,6 +77,7 @@ from nova import crypto from nova import db from nova import exception from nova import flags +from nova import log as logging from nova import quota from nova import utils from nova.auth import manager @@ -499,6 +500,15 @@ class ServiceCommands(object): db.service_update(ctxt, svc['id'], {'disabled': True}) +class LogCommands(object): + def request(self, request_id, logfile='/var/log/nova.log'): + """Show all fields in the log for the given request. Assumes you + haven't changed the log format too much. + ARGS: request_id [logfile]""" + lines = utils.execute("cat %s | grep '\[%s '" % (logfile, request_id)) + print re.sub('#012', "\n", "\n".join(lines)) + + CATEGORIES = [ ('user', UserCommands), ('project', ProjectCommands), @@ -507,7 +517,8 @@ CATEGORIES = [ ('vpn', VpnCommands), ('floating', FloatingIpCommands), ('network', NetworkCommands), - ('service', ServiceCommands)] + ('service', ServiceCommands), + ('log', LogCommands)] def lazy_match(name, key_value_tuples): @@ -546,9 +557,7 @@ def main(): utils.default_flagfile() argv = FLAGS(sys.argv) - if FLAGS.verbose: - logging.getLogger().setLevel(logging.DEBUG) - + logging._set_log_levels() script_name = argv.pop(0) if len(argv) < 1: print script_name + " category action []" diff --git a/bin/nova-spoolsentry b/bin/nova-spoolsentry new file mode 100644 index 000000000..ab20268a9 --- /dev/null +++ b/bin/nova-spoolsentry @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +import base64 +import json +import logging +import os +import shutil +import sys +import urllib +import urllib2 +try: + import cPickle as pickle +except: + import pickle + + +class SpoolSentry(object): + def __init__(self, spool_dir, sentry_url, key=None): + self.spool_dir = spool_dir + self.sentry_url = sentry_url + self.key = key + + def process(self): + for fname in os.listdir(self.spool_dir): + if fname == "processed": + continue + try: + sourcefile = "%s/%s" % (self.spool_dir, fname) + with open(sourcefile) as f: + fdata = f.read() + data_from_json = json.loads(fdata) + data = self.build_data(data_from_json) + self.send_data(data) + destfile = "%s/processed/%s" % (self.spool_dir, fname) + shutil.move(sourcefile, destfile) + except: + logging.exception("Unable to upload record %s", fname) + raise + + def build_data(self, filejson): + env = {'SERVER_NAME': 'unknown', 'SERVER_PORT': '0000', + 'SCRIPT_NAME': '/unknown/', 'PATH_INFO': 'unknown'} + if filejson['env']: + env = json.loads(filejson['env']) + url = "http://%s:%s%s%s" % (env['SERVER_NAME'], env['SERVER_PORT'], + env['SCRIPT_NAME'], env['PATH_INFO']) + rv = {'logger': filejson['logger'], 'level': logging.ERROR, + 'server_name': filejson['host'], 'url': url, + 'message': filejson['message'], + 'traceback': filejson['traceback']} + rv['data'] = {} + if filejson['env']: + rv['data']['META'] = env + if filejson['request_id']: + rv['data']['request_id'] = filejson['request_id'] + return rv + + def send_data(self, data): + data = { + 'data': base64.b64encode(pickle.dumps(data).encode('zlib')), + 'key': self.key + } + req = urllib2.Request(self.sentry_url) + res = urllib2.urlopen(req, urllib.urlencode(data)) + if res.getcode() != 200: + raise Exception("Bad HTTP code: %s" % res.getcode()) + txt = res.read() + +if __name__ == '__main__': + sentryurl = 'http://127.0.0.1/sentry/store/' + key = '' + spooldir = '/var/spool/nova' + if len(sys.argv) > 1: + sentryurl = sys.argv[1] + if len(sys.argv) > 2: + key = sys.argv[2] + if len(sys.argv) > 3: + spooldir = sys.argv[3] + SpoolSentry(spooldir, sentryurl, key).process() -- cgit From b9576a9f73195656f4a0a1327cd6bee3c4a6b6c9 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Tue, 4 Jan 2011 00:26:41 -0500 Subject: Final few log tweaks, i18n, levels, including contexts, etc. --- bin/nova-dhcpbridge | 15 ++++++--------- bin/nova-instancemonitor | 2 +- bin/nova-manage | 2 -- 3 files changed, 7 insertions(+), 12 deletions(-) (limited to 'bin') diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index cecc1c80c..1a994d956 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -49,16 +49,13 @@ flags.DECLARE('network_size', 'nova.network.manager') flags.DECLARE('num_networks', 'nova.network.manager') flags.DECLARE('update_dhcp_on_disassociate', 'nova.network.manager') - -LOG = logging.getLogger('nova-dhcpbridge') -if FLAGS.verbose: - LOG.setLevel(logging.DEBUG) +LOG = logging.getLogger('nova.dhcpbridge') def add_lease(mac, ip_address, _hostname, _interface): """Set the IP that was assigned by the DHCP server.""" if FLAGS.fake_rabbit: - LOG.debug("leasing ip") + LOG.debug(_("leasing ip")) network_manager = utils.import_object(FLAGS.network_manager) network_manager.lease_fixed_ip(context.get_admin_context(), mac, @@ -73,14 +70,14 @@ def add_lease(mac, ip_address, _hostname, _interface): def old_lease(mac, ip_address, hostname, interface): """Update just as add lease.""" - LOG.debug("Adopted old lease or got a change of mac/hostname") + LOG.debug(_("Adopted old lease or got a change of mac/hostname")) add_lease(mac, ip_address, hostname, interface) def del_lease(mac, ip_address, _hostname, _interface): """Called when a lease expires.""" if FLAGS.fake_rabbit: - LOG.debug("releasing ip") + LOG.debug(_("releasing ip")) network_manager = utils.import_object(FLAGS.network_manager) network_manager.release_fixed_ip(context.get_admin_context(), mac, @@ -123,8 +120,8 @@ def main(): mac = argv[2] ip = argv[3] hostname = argv[4] - LOG.debug("Called %s for mac %s with ip %s and " - "hostname %s on interface %s", + LOG.debug(_("Called %s for mac %s with ip %s and " + "hostname %s on interface %s"), action, mac, ip, hostname, interface) globals()[action + '_lease'](mac, ip, hostname, interface) else: diff --git a/bin/nova-instancemonitor b/bin/nova-instancemonitor index 17f573b9d..7dca02014 100755 --- a/bin/nova-instancemonitor +++ b/bin/nova-instancemonitor @@ -44,7 +44,7 @@ from nova.compute import monitor # TODO(todd): shouldn't this be done with flags? And what about verbose? logging.getLogger('boto').setLevel(logging.WARN) -LOG = logging.getLogger('nova-instancemonitor') +LOG = logging.getLogger('nova.instancemonitor') if __name__ == '__main__': diff --git a/bin/nova-manage b/bin/nova-manage index 169ab5f62..40f540e5b 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -77,7 +77,6 @@ from nova import crypto from nova import db from nova import exception from nova import flags -from nova import log as logging from nova import quota from nova import utils from nova.auth import manager @@ -557,7 +556,6 @@ def main(): utils.default_flagfile() argv = FLAGS(sys.argv) - logging._set_log_levels() script_name = argv.pop(0) if len(argv) < 1: print script_name + " category action []" -- cgit From 35d3050511ef513ff440fbd9f8b44695ea8be797 Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Tue, 4 Jan 2011 14:07:46 -0800 Subject: rename Easy API to Direct API --- bin/nova-direct-api | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++ bin/nova-easy-api | 61 ----------------------------------------------------- 2 files changed, 61 insertions(+), 61 deletions(-) create mode 100755 bin/nova-direct-api delete mode 100755 bin/nova-easy-api (limited to 'bin') diff --git a/bin/nova-direct-api b/bin/nova-direct-api new file mode 100755 index 000000000..43046e6c2 --- /dev/null +++ b/bin/nova-direct-api @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# pylint: disable-msg=C0103 +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Starter script for Nova Easy API.""" + +import gettext +import os +import sys + +# If ../nova/__init__.py exists, add ../ to Python search path, so that +# it will override what happens to be installed in /usr/(local/)lib/python... +possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), + os.pardir, + os.pardir)) +if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): + sys.path.insert(0, possible_topdir) + +gettext.install('nova', unicode=1) + +from nova import flags +from nova import utils +from nova import wsgi +from nova.api import direct +from nova.compute import api as compute_api + + +FLAGS = flags.FLAGS +flags.DEFINE_integer('direct_port', 8001, 'Direct API port') +flags.DEFINE_string('direct_host', '0.0.0.0', 'Direct API host') + +if __name__ == '__main__': + utils.default_flagfile() + FLAGS(sys.argv) + + direct.register_service('compute', compute_api.ComputeAPI()) + direct.register_service('reflect', direct.Reflection()) + router = direct.Router() + with_json = direct.JsonParamsMiddleware(router) + with_req = direct.PostParamsMiddleware(with_json) + with_auth = direct.DelegatedAuthMiddleware(with_req) + + server = wsgi.Server() + server.start(with_auth, FLAGS.direct_port, host=FLAGS.direct_host) + server.wait() diff --git a/bin/nova-easy-api b/bin/nova-easy-api deleted file mode 100755 index e8e86b4fb..000000000 --- a/bin/nova-easy-api +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python -# pylint: disable-msg=C0103 -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Starter script for Nova Easy API.""" - -import gettext -import os -import sys - -# If ../nova/__init__.py exists, add ../ to Python search path, so that -# it will override what happens to be installed in /usr/(local/)lib/python... -possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), - os.pardir, - os.pardir)) -if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import flags -from nova import utils -from nova import wsgi -from nova.api import easy -from nova.compute import api as compute_api - - -FLAGS = flags.FLAGS -flags.DEFINE_integer('easy_port', 8001, 'Easy API port') -flags.DEFINE_string('easy_host', '0.0.0.0', 'Easy API host') - -if __name__ == '__main__': - utils.default_flagfile() - FLAGS(sys.argv) - - easy.register_service('compute', compute_api.ComputeAPI()) - easy.register_service('reflect', easy.Reflection()) - router = easy.SundayMorning() - with_json = easy.JsonParamsMiddleware(router) - with_req = easy.ReqParamsMiddleware(with_json) - with_auth = easy.DelegatedAuthMiddleware(with_req) - - server = wsgi.Server() - server.start(with_auth, FLAGS.easy_port, host=FLAGS.easy_host) - server.wait() -- cgit From 1a66771aaf49d16d4131a1a787a1fda39aa680fd Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Tue, 4 Jan 2011 14:37:04 -0800 Subject: fix typo in stack tool --- bin/stack | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/stack b/bin/stack index 284dbf4fc..42feacd63 100755 --- a/bin/stack +++ b/bin/stack @@ -139,7 +139,7 @@ if __name__ == '__main__': method = args.pop(0) params = {} for x in args: - key, value = args.split('=', 1) + key, value = x.split('=', 1) params[key] = value pprint.pprint(do_request(controller, method, params)) -- cgit From 5679caa48b90ecebf9a1143bf92cec0e7c0ed1f8 Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Tue, 4 Jan 2011 14:39:48 -0800 Subject: rename easy to direct in the scripts --- bin/nova-direct-api | 2 +- bin/stack | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'bin') diff --git a/bin/nova-direct-api b/bin/nova-direct-api index 43046e6c2..e7dd14fb2 100755 --- a/bin/nova-direct-api +++ b/bin/nova-direct-api @@ -18,7 +18,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Starter script for Nova Easy API.""" +"""Starter script for Nova Direct API.""" import gettext import os diff --git a/bin/stack b/bin/stack index 42feacd63..7a6ce5960 100755 --- a/bin/stack +++ b/bin/stack @@ -17,7 +17,7 @@ # License for the specific language governing permissions and limitations # under the License. -"""CLI for the Easy API.""" +"""CLI for the Direct API.""" import eventlet eventlet.monkey_patch() @@ -42,10 +42,10 @@ from nova import utils FLAGS = gflags.FLAGS -gflags.DEFINE_string('host', '127.0.0.1', 'Easy API host') -gflags.DEFINE_integer('port', 8001, 'Easy API host') -gflags.DEFINE_string('user', 'user1', 'Easy API username') -gflags.DEFINE_string('project', 'proj1', 'Easy API project') +gflags.DEFINE_string('host', '127.0.0.1', 'Direct API host') +gflags.DEFINE_integer('port', 8001, 'Direct API host') +gflags.DEFINE_string('user', 'user1', 'Direct API username') +gflags.DEFINE_string('project', 'proj1', 'Direct API project') USAGE = """usage: stack [options] [arg1=value arg2=value] -- cgit From 2491c2484f025cb3f061fcc6a5c6915006feb47b Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Tue, 4 Jan 2011 18:16:16 -0500 Subject: Make paste the default api pattern. * get rid of the --use_lockout flag since it will be specified in paste config (Example line is commented out in etc/nova-api.conf, factory is in place) * remove old nova-api binary and promote nova-api-paste * change how we store ec2 parameters to bin the the ApiRequest * get rid of Router, since paste.urlmap is equally effective (Requestify now gets passed the name of the controller requests are to.) --- bin/nova-api | 75 ++++++++++++++++++++++++++++++------ bin/nova-api-paste | 109 ----------------------------------------------------- 2 files changed, 64 insertions(+), 120 deletions(-) delete mode 100755 bin/nova-api-paste (limited to 'bin') diff --git a/bin/nova-api b/bin/nova-api index 1c671201e..6ee833a18 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -21,9 +21,12 @@ """Starter script for Nova API.""" import gettext +import logging import os import sys +from paste import deploy + # If ../nova/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), @@ -34,23 +37,73 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): gettext.install('nova', unicode=1) -from nova import api from nova import flags -from nova import utils from nova import wsgi +LOG = logging.getLogger('nova.api') +LOG.setLevel(logging.DEBUG) +LOG.addHandler(logging.StreamHandler()) FLAGS = flags.FLAGS -flags.DEFINE_integer('osapi_port', 8774, 'OpenStack API port') -flags.DEFINE_string('osapi_host', '0.0.0.0', 'OpenStack API host') -flags.DEFINE_integer('ec2api_port', 8773, 'EC2 API port') -flags.DEFINE_string('ec2api_host', '0.0.0.0', 'EC2 API host') +API_ENDPOINTS = ['ec2', 'openstack'] -if __name__ == '__main__': - utils.default_flagfile() - FLAGS(sys.argv) + +def load_configuration(paste_config): + """Load the paste configuration from the config file and return it.""" + config = None + # Try each known name to get the global DEFAULTS, which will give ports + for name in API_ENDPOINTS: + try: + config = deploy.appconfig("config:%s" % paste_config, name=name) + except LookupError: + pass + if config: + verbose = config.get('verbose', None) + if verbose: + FLAGS.verbose = int(verbose) == 1 + if FLAGS.verbose: + logging.getLogger().setLevel(logging.DEBUG) + return config + LOG.debug(_("Paste config at %s has no secion for known apis"), + paste_config) + print _("Paste config at %s has no secion for any known apis") % \ + paste_config + os.exit(1) + + +def launch_api(paste_config_file, section, server, port, host): + """Launch an api server from the specified port and IP.""" + LOG.debug(_("Launching %s api on %s:%s"), section, host, port) + app = deploy.loadapp('config:%s' % paste_config_file, name=section) + server.start(app, int(port), host) + + +def run_app(paste_config_file): + LOG.debug(_("Using paste.deploy config at: %s"), configfile) + config = load_configuration(paste_config_file) + LOG.debug(_("Configuration: %r"), config) server = wsgi.Server() - server.start(api.API('os'), FLAGS.osapi_port, host=FLAGS.osapi_host) - server.start(api.API('ec2'), FLAGS.ec2api_port, host=FLAGS.ec2api_host) + ip = config.get('host', '0.0.0.0') + for api in API_ENDPOINTS: + port = config.get("%s_port" % api, None) + if not port: + continue + host = config.get("%s_host" % api, ip) + launch_api(configfile, api, server, port, host) + LOG.debug(_("All api servers launched, now waiting")) server.wait() + + +if __name__ == '__main__': + FLAGS(sys.argv) + configfiles = ['/etc/nova/nova-api.conf'] + if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): + configfiles.insert(0, + os.path.join(possible_topdir, 'etc', 'nova-api.conf')) + for configfile in configfiles: + if os.path.exists(configfile): + run_app(configfile) + break + else: + LOG.debug(_("Skipping missing configuration: %s"), configfile) diff --git a/bin/nova-api-paste b/bin/nova-api-paste deleted file mode 100755 index 6ee833a18..000000000 --- a/bin/nova-api-paste +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python -# pylint: disable-msg=C0103 -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Starter script for Nova API.""" - -import gettext -import logging -import os -import sys - -from paste import deploy - -# If ../nova/__init__.py exists, add ../ to Python search path, so that -# it will override what happens to be installed in /usr/(local/)lib/python... -possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), - os.pardir, - os.pardir)) -if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import flags -from nova import wsgi - -LOG = logging.getLogger('nova.api') -LOG.setLevel(logging.DEBUG) -LOG.addHandler(logging.StreamHandler()) - -FLAGS = flags.FLAGS - -API_ENDPOINTS = ['ec2', 'openstack'] - - -def load_configuration(paste_config): - """Load the paste configuration from the config file and return it.""" - config = None - # Try each known name to get the global DEFAULTS, which will give ports - for name in API_ENDPOINTS: - try: - config = deploy.appconfig("config:%s" % paste_config, name=name) - except LookupError: - pass - if config: - verbose = config.get('verbose', None) - if verbose: - FLAGS.verbose = int(verbose) == 1 - if FLAGS.verbose: - logging.getLogger().setLevel(logging.DEBUG) - return config - LOG.debug(_("Paste config at %s has no secion for known apis"), - paste_config) - print _("Paste config at %s has no secion for any known apis") % \ - paste_config - os.exit(1) - - -def launch_api(paste_config_file, section, server, port, host): - """Launch an api server from the specified port and IP.""" - LOG.debug(_("Launching %s api on %s:%s"), section, host, port) - app = deploy.loadapp('config:%s' % paste_config_file, name=section) - server.start(app, int(port), host) - - -def run_app(paste_config_file): - LOG.debug(_("Using paste.deploy config at: %s"), configfile) - config = load_configuration(paste_config_file) - LOG.debug(_("Configuration: %r"), config) - server = wsgi.Server() - ip = config.get('host', '0.0.0.0') - for api in API_ENDPOINTS: - port = config.get("%s_port" % api, None) - if not port: - continue - host = config.get("%s_host" % api, ip) - launch_api(configfile, api, server, port, host) - LOG.debug(_("All api servers launched, now waiting")) - server.wait() - - -if __name__ == '__main__': - FLAGS(sys.argv) - configfiles = ['/etc/nova/nova-api.conf'] - if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): - configfiles.insert(0, - os.path.join(possible_topdir, 'etc', 'nova-api.conf')) - for configfile in configfiles: - if os.path.exists(configfile): - run_app(configfile) - break - else: - LOG.debug(_("Skipping missing configuration: %s"), configfile) -- cgit From b437a98738c7a564205d1b27e36b844cd54445d1 Mon Sep 17 00:00:00 2001 From: Monsyne Dragon Date: Wed, 5 Jan 2011 14:16:14 -0600 Subject: add in xs-console worker and tests. --- bin/nova-combined | 5 +++-- bin/nova-console | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100755 bin/nova-console (limited to 'bin') diff --git a/bin/nova-combined b/bin/nova-combined index 53322f1a0..a1d2cdc66 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -56,11 +56,12 @@ if __name__ == '__main__': compute = service.Service.create(binary='nova-compute') network = service.Service.create(binary='nova-network') - volume = service.Service.create(binary='nova-volume') +# volume = service.Service.create(binary='nova-volume') scheduler = service.Service.create(binary='nova-scheduler') #objectstore = service.Service.create(binary='nova-objectstore') - service.serve(compute, network, volume, scheduler) +# service.serve(compute, network, volume, scheduler) + service.serve(compute, network, scheduler) server = wsgi.Server() server.start(api.API('os'), FLAGS.osapi_port, host=FLAGS.osapi_host) diff --git a/bin/nova-console b/bin/nova-console new file mode 100755 index 000000000..802cc80b6 --- /dev/null +++ b/bin/nova-console @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2010 Openstack, LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Starter script for Nova Console Proxy.""" + +import eventlet +eventlet.monkey_patch() + +import gettext +import os +import sys + +# If ../nova/__init__.py exists, add ../ to Python search path, so that +# it will override what happens to be installed in /usr/(local/)lib/python... +possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), + os.pardir, + os.pardir)) +if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): + sys.path.insert(0, possible_topdir) + +gettext.install('nova', unicode=1) + +from nova import service +from nova import utils + +if __name__ == '__main__': + utils.default_flagfile() + service.serve() + service.wait() -- cgit From b55940e8e3d977960ff60f4cb7cff4b6ea2e8fb8 Mon Sep 17 00:00:00 2001 From: Monsyne Dragon Date: Wed, 5 Jan 2011 22:11:05 -0600 Subject: fix some glitches due to someone removing instanc.internal_id (not that I mind) remove accidental change to nova-combined script --- bin/nova-combined | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'bin') diff --git a/bin/nova-combined b/bin/nova-combined index a1d2cdc66..53322f1a0 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -56,12 +56,11 @@ if __name__ == '__main__': compute = service.Service.create(binary='nova-compute') network = service.Service.create(binary='nova-network') -# volume = service.Service.create(binary='nova-volume') + volume = service.Service.create(binary='nova-volume') scheduler = service.Service.create(binary='nova-scheduler') #objectstore = service.Service.create(binary='nova-objectstore') -# service.serve(compute, network, volume, scheduler) - service.serve(compute, network, scheduler) + service.serve(compute, network, volume, scheduler) server = wsgi.Server() server.start(api.API('os'), FLAGS.osapi_port, host=FLAGS.osapi_host) -- cgit From 8952629c576498c3b576a1f9085a8d1b850e8639 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Fri, 7 Jan 2011 14:09:38 -0500 Subject: pep8 fixes --- bin/nova-logspool | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/nova-logspool b/bin/nova-logspool index d5aef4756..097459b12 100644 --- a/bin/nova-logspool +++ b/bin/nova-logspool @@ -28,7 +28,6 @@ import sys class Request(object): - def __init__(self): self.time = "" self.host = "" @@ -67,6 +66,7 @@ class Request(object): 'host': self.host, 'env': self.env, 'logger': self.logger, 'request_id': self.request_id} + class LogReader(object): def __init__(self, filename): self.filename = filename -- cgit From 20a326c1724fe74b196db5695a0ac2ecf040c0d8 Mon Sep 17 00:00:00 2001 From: Ryan Lane Date: Mon, 10 Jan 2011 15:02:29 +0000 Subject: Adding modify option for projects --- bin/nova-manage | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index 40f540e5b..a81e407e9 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -333,6 +333,11 @@ class ProjectCommands(object): arguments: name project_manager [description]""" self.manager.create_project(name, project_manager, description) + def modify(self, name, project_manaber, description=None): + """Modifies a project + arguments: name project_manager [description]""" + self.manager.modify_project(name, project_manager, description) + def delete(self, name): """Deletes an existing project arguments: name""" -- cgit From 8d04f68f00d5cd37f13028a4ee5909530ea9c92c Mon Sep 17 00:00:00 2001 From: Ryan Lane Date: Mon, 10 Jan 2011 15:13:30 +0000 Subject: Typo fix --- bin/nova-manage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index a81e407e9..3f5957190 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -333,7 +333,7 @@ class ProjectCommands(object): arguments: name project_manager [description]""" self.manager.create_project(name, project_manager, description) - def modify(self, name, project_manaber, description=None): + def modify(self, name, project_manager, description=None): """Modifies a project arguments: name project_manager [description]""" self.manager.modify_project(name, project_manager, description) -- cgit From 94f3782eb27fd63c64845f9ab59039d07ac7ba8c Mon Sep 17 00:00:00 2001 From: Monsyne Dragon Date: Mon, 10 Jan 2011 14:59:32 -0600 Subject: remove uneeded superclass --- bin/nova-combined | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/nova-combined b/bin/nova-combined index 53322f1a0..4e49fd1fc 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -60,7 +60,8 @@ if __name__ == '__main__': scheduler = service.Service.create(binary='nova-scheduler') #objectstore = service.Service.create(binary='nova-objectstore') - service.serve(compute, network, volume, scheduler) + #service.serve(compute, network, volume, scheduler) + service.serve(compute, network, scheduler) server = wsgi.Server() server.start(api.API('os'), FLAGS.osapi_port, host=FLAGS.osapi_host) -- cgit From d6a66d13718a41d5146d713ced192e795e72457e Mon Sep 17 00:00:00 2001 From: Monsyne Dragon Date: Mon, 10 Jan 2011 15:00:30 -0600 Subject: whups, fix accidental change to nova-combined --- bin/nova-combined | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'bin') diff --git a/bin/nova-combined b/bin/nova-combined index 4e49fd1fc..53322f1a0 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -60,8 +60,7 @@ if __name__ == '__main__': scheduler = service.Service.create(binary='nova-scheduler') #objectstore = service.Service.create(binary='nova-objectstore') - #service.serve(compute, network, volume, scheduler) - service.serve(compute, network, scheduler) + service.serve(compute, network, volume, scheduler) server = wsgi.Server() server.start(api.API('os'), FLAGS.osapi_port, host=FLAGS.osapi_host) -- cgit From 4edfa8ea26f8e820674e8bebbe34b6ed5885a69b Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Mon, 10 Jan 2011 13:44:45 -0800 Subject: consolidate boto_extensions.py and euca-get-ajax-console, fix bugs from previous trunk merge --- bin/nova-ajax-console-proxy | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/nova-ajax-console-proxy b/bin/nova-ajax-console-proxy index 53b779711..2bc407658 100755 --- a/bin/nova-ajax-console-proxy +++ b/bin/nova-ajax-console-proxy @@ -24,6 +24,7 @@ from eventlet import greenthread from eventlet.green import urllib2 import exceptions +import gettext import logging import os import sys @@ -38,9 +39,12 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')): sys.path.insert(0, possible_topdir) +gettext.install('nova', unicode=1) + from nova import flags -from nova import utils +from nova import log as logging from nova import rpc +from nova import utils from nova import wsgi FLAGS = flags.FLAGS @@ -48,6 +52,10 @@ FLAGS = flags.FLAGS flags.DEFINE_integer('ajax_console_idle_timeout', 300, 'Seconds before idle connection destroyed') +LOG = logging.getLogger('nova.ajax_console_proxy') +LOG.setLevel(logging.DEBUG) +LOG.addHandler(logging.StreamHandler()) + class AjaxConsoleProxy(object): tokens = {} @@ -83,6 +91,9 @@ class AjaxConsoleProxy(object): start_response("200 OK", info.dict.items()) return body except (exceptions.KeyError): + if env['PATH_INFO'] != '/favicon.ico': + LOG.audit("Unauthorized request %s, %s" + % (req_url, str(env))) start_response("401 NOT AUTHORIZED", []) return "Not Authorized" except Exception: -- cgit From 5afd9848ad09414c00062ceebdad45bca0604888 Mon Sep 17 00:00:00 2001 From: Muneyuki Noguchi Date: Tue, 11 Jan 2011 18:01:23 +0900 Subject: Add support for EBS volumes to the live migration feature. Currently, only AoE is supported. --- bin/nova-manage | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index 7c87d21ff..fa044859d 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -83,8 +83,6 @@ from nova import rpc from nova.cloudpipe import pipelib from nova.api.ec2 import cloud - - FLAGS = flags.FLAGS flags.DECLARE('fixed_range', 'nova.network.manager') flags.DECLARE('num_networks', 'nova.network.manager') @@ -462,6 +460,10 @@ class InstanceCommands(object): def live_migration(self, ec2_id, dest): """live_migration""" + if FLAGS.volume_driver != 'nova.volume.driver.AOEDriver': + raise exception.Error('Only AOEDriver is supported for now. ' + 'Sorry.') + logging.basicConfig() ctxt = context.get_admin_context() @@ -491,7 +493,6 @@ class InstanceCommands(object): class HostCommands(object): """Class for mangaging host(physical nodes).""" - def list(self): """describe host list.""" @@ -502,7 +503,6 @@ class HostCommands(object): for host_ref in host_refs: print host_ref['name'] - def show(self, host): """describe cpu/memory/hdd info for host.""" @@ -546,6 +546,7 @@ CATEGORIES = [ ('instance', InstanceCommands), ('host', HostCommands)] + def lazy_match(name, key_value_tuples): """Finds all objects that have a key that case insensitively contains [name] key_value_tuples is a list of tuples of the form (key, value) -- cgit From 1629dcf935a29c01d4e4ad509e33356daa93b051 Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Wed, 12 Jan 2011 11:26:22 +0900 Subject: Fixed for pep8 Remove temporary debugging --- bin/nova-manage | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index 04ecc8c10..7331186c7 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -91,6 +91,7 @@ flags.DECLARE('vlan_start', 'nova.network.manager') flags.DECLARE('vpn_start', 'nova.network.manager') flags.DECLARE('fixed_range_v6', 'nova.network.manager') + class VpnCommands(object): """Class for managing VPNs.""" @@ -432,11 +433,12 @@ class NetworkCommands(object): """Class for managing networks.""" def create(self, fixed_range=None, num_networks=None, - network_size=None, vlan_start=None, vpn_start=None,fixed_range_v6=None): + network_size=None, vlan_start=None, vpn_start=None, + fixed_range_v6=None): """Creates fixed ips for host by range arguments: [fixed_range=FLAG], [num_networks=FLAG], [network_size=FLAG], [vlan_start=FLAG], - [vpn_start=FLAG],[fixed_range_v6=FLAG]""" + [vpn_start=FLAG], [fixed_range_v6=FLAG]""" if not fixed_range: fixed_range = FLAGS.fixed_range if not num_networks: @@ -453,9 +455,7 @@ class NetworkCommands(object): net_manager.create_networks(context.get_admin_context(), fixed_range, int(num_networks), int(network_size), int(vlan_start), - int(vpn_start),fixed_range_v6) - - + int(vpn_start), fixed_range_v6) class ServiceCommands(object): -- cgit From 3e9d08bded2f504a5dd03712c82e981f73ae16ed Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Wed, 12 Jan 2011 14:16:51 -0400 Subject: change novarc template from cc_port to osapi_port. Removed osapi_port from bin scripts. --- bin/nova-api | 1 - bin/nova-combined | 1 - 2 files changed, 2 deletions(-) (limited to 'bin') diff --git a/bin/nova-api b/bin/nova-api index 1c671201e..c7cbb3ab4 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -41,7 +41,6 @@ from nova import wsgi FLAGS = flags.FLAGS -flags.DEFINE_integer('osapi_port', 8774, 'OpenStack API port') flags.DEFINE_string('osapi_host', '0.0.0.0', 'OpenStack API host') flags.DEFINE_integer('ec2api_port', 8773, 'EC2 API port') flags.DEFINE_string('ec2api_host', '0.0.0.0', 'EC2 API host') diff --git a/bin/nova-combined b/bin/nova-combined index 53322f1a0..f932fdfd5 100755 --- a/bin/nova-combined +++ b/bin/nova-combined @@ -44,7 +44,6 @@ from nova import wsgi FLAGS = flags.FLAGS -flags.DEFINE_integer('osapi_port', 8774, 'OpenStack API port') flags.DEFINE_string('osapi_host', '0.0.0.0', 'OpenStack API host') flags.DEFINE_integer('ec2api_port', 8773, 'EC2 API port') flags.DEFINE_string('ec2api_host', '0.0.0.0', 'EC2 API host') -- cgit From 982067aefcd656de7751623e272d9b6cf1447dc3 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Wed, 12 Jan 2011 15:12:08 -0500 Subject: Stop error messages for logs when running nova-manage. --- bin/nova-manage | 2 ++ 1 file changed, 2 insertions(+) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index 3f5957190..3e290567c 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -77,12 +77,14 @@ from nova import crypto from nova import db from nova import exception from nova import flags +from nova import log as logging from nova import quota from nova import utils from nova.auth import manager from nova.cloudpipe import pipelib +logging.basicConfig() FLAGS = flags.FLAGS flags.DECLARE('fixed_range', 'nova.network.manager') flags.DECLARE('num_networks', 'nova.network.manager') -- cgit From 4f5c0c64ec9d397048dfd7b8d5c007ec0fa39ec5 Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Wed, 12 Jan 2011 16:57:04 -0800 Subject: add support for database migration --- bin/nova-manage | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index 3e290567c..c441fa7f2 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -82,6 +82,7 @@ from nova import quota from nova import utils from nova.auth import manager from nova.cloudpipe import pipelib +from nova.db import migration logging.basicConfig() @@ -515,6 +516,22 @@ class LogCommands(object): print re.sub('#012', "\n", "\n".join(lines)) +class DbCommands(object): + """Class for managing the database.""" + + def __init__(self): + pass + + def sync(self, version=None): + """adds role to user + if project is specified, adds project specific role + arguments: user, role [project]""" + return migration.db_sync(version) + + def version(self): + print migration.db_version() + + CATEGORIES = [ ('user', UserCommands), ('project', ProjectCommands), @@ -524,7 +541,8 @@ CATEGORIES = [ ('floating', FloatingIpCommands), ('network', NetworkCommands), ('service', ServiceCommands), - ('log', LogCommands)] + ('log', LogCommands), + ('db', DbCommands)] def lazy_match(name, key_value_tuples): -- cgit From c57ccba743c54786e28317194000bcf22dc5b69e Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Fri, 14 Jan 2011 08:26:25 +0900 Subject: checking based on pep8 --- bin/nova-manage | 1 - 1 file changed, 1 deletion(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index fb6b06694..b8a181343 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -468,7 +468,6 @@ class InstanceCommands(object): def live_migration(self, ec2_id, dest): """live_migration""" - if FLAGS.connection_type != 'libvirt': raise exception.Error('Only KVM is supported for now. ' 'Sorry.') -- cgit From 525544e689334346305ecc11552105fc1b32a5dd Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Sun, 16 Jan 2011 14:54:35 +0900 Subject: merged to rev 561 and fixed based on reviewer's comment --- bin/nova-manage | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index b8a181343..6bd6aef64 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -62,6 +62,7 @@ import time import IPy + # If ../nova/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), @@ -468,17 +469,19 @@ class InstanceCommands(object): def live_migration(self, ec2_id, dest): """live_migration""" + ctxt = context.get_admin_context() + instance_id = cloud.ec2_id_to_id(ec2_id) + if FLAGS.connection_type != 'libvirt': - raise exception.Error('Only KVM is supported for now. ' - 'Sorry.') + msg = _('Only KVM is supported for now. Sorry!') + raise exception.Error(msg) if FLAGS.volume_driver != 'nova.volume.driver.AOEDriver': - raise exception.Error('Only AOEDriver is supported for now. ' - 'Sorry.') - - logging.basicConfig() - ctxt = context.get_admin_context() - instance_id = cloud.ec2_id_to_id(ec2_id) + instance_ref = db.instance_get(instance_id) + if len(instance_ref['volumes']) != 0: + msg = _(("""Volumes attached by ISCSIDriver""" + """ are not supported. Sorry!""")) + raise exception.Error(msg) rpc.call(ctxt, FLAGS.scheduler_topic, @@ -501,16 +504,15 @@ class HostCommands(object): # To supress msg: No handlers could be found for logger "amqplib" logging.basicConfig() - host_refs = db.host_get_all(context.get_admin_context()) - for host_ref in host_refs: - print host_ref['name'] + service_refs = db.service_get_all(context.get_admin_context()) + hosts = [ h['host'] for h in service_refs] + hosts = list(set(hosts)) + for host in hosts: + print host def show(self, host): """describe cpu/memory/hdd info for host.""" - # To supress msg: No handlers could be found for logger "amqplib" - logging.basicConfig() - result = rpc.call(context.get_admin_context(), FLAGS.scheduler_topic, {"method": "show_host_resource", -- cgit From d91229f7a3b60095677e1bb76a548668c59ee9e2 Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Tue, 18 Jan 2011 11:01:16 -0800 Subject: revert live_migration branch --- bin/nova-manage | 82 +-------------------------------------------------------- 1 file changed, 1 insertion(+), 81 deletions(-) (limited to 'bin') diff --git a/bin/nova-manage b/bin/nova-manage index 1ad3120b8..b5842b595 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -62,7 +62,6 @@ import time import IPy - # If ../nova/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), @@ -82,9 +81,8 @@ from nova import log as logging from nova import quota from nova import utils from nova.auth import manager -from nova import rpc from nova.cloudpipe import pipelib -from nova.api.ec2 import cloud + logging.basicConfig() FLAGS = flags.FLAGS @@ -467,82 +465,6 @@ class NetworkCommands(object): int(vpn_start), fixed_range_v6) -class InstanceCommands(object): - """Class for mangaging VM instances.""" - - def live_migration(self, ec2_id, dest): - """live_migration""" - - ctxt = context.get_admin_context() - instance_id = cloud.ec2_id_to_id(ec2_id) - - if FLAGS.connection_type != 'libvirt': - msg = _('Only KVM is supported for now. Sorry!') - raise exception.Error(msg) - - if FLAGS.volume_driver != 'nova.volume.driver.AOEDriver': - instance_ref = db.instance_get(ctxt, instance_id) - if len(instance_ref['volumes']) != 0: - msg = _(("""Volumes attached by ISCSIDriver""" - """ are not supported. Sorry!""")) - raise exception.Error(msg) - - rpc.call(ctxt, - FLAGS.scheduler_topic, - {"method": "live_migration", - "args": {"instance_id": instance_id, - "dest": dest, - "topic": FLAGS.compute_topic}}) - - msg = 'Migration of %s initiated. ' % ec2_id - msg += 'Check its progress using euca-describe-instances.' - print msg - - -class HostCommands(object): - """Class for mangaging host(physical nodes).""" - - def list(self): - """describe host list.""" - - # To supress msg: No handlers could be found for logger "amqplib" - logging.basicConfig() - - service_refs = db.service_get_all(context.get_admin_context()) - hosts = [h['host'] for h in service_refs] - hosts = list(set(hosts)) - for host in hosts: - print host - - def show(self, host): - """describe cpu/memory/hdd info for host.""" - - result = rpc.call(context.get_admin_context(), - FLAGS.scheduler_topic, - {"method": "show_host_resource", - "args": {"host": host}}) - - # Checking result msg format is necessary, that will have done - # when this feture is included in API. - if type(result) != dict: - print 'Unexpected error occurs' - elif not result['ret']: - print '%s' % result['msg'] - else: - cpu = result['phy_resource']['vcpus'] - mem = result['phy_resource']['memory_mb'] - hdd = result['phy_resource']['local_gb'] - - print 'HOST\t\tPROJECT\t\tcpu\tmem(mb)\tdisk(gb)' - print '%s\t\t\t%s\t%s\t%s' % (host, cpu, mem, hdd) - for p_id, val in result['usage'].items(): - print '%s\t%s\t\t%s\t%s\t%s' % (host, - p_id, - val['vcpus'], - val['memory_mb'], - val['local_gb']) - - class ServiceCommands(object): """Enable and disable running services""" @@ -605,8 +527,6 @@ CATEGORIES = [ ('vpn', VpnCommands), ('floating', FloatingIpCommands), ('network', NetworkCommands), - ('instance', InstanceCommands), - ('host', HostCommands), ('service', ServiceCommands), ('log', LogCommands)] -- cgit