From d9c38b9fb7a57049ee9ee79551f8816bf39e673a Mon Sep 17 00:00:00 2001 From: Nikolay Markov Date: Thu, 20 Sep 2012 17:44:55 +0400 Subject: [PATCH] agent fix and installation test --- .gitignore | 1 - bin/agent | 85 ++- cookbooks/nailgun/recipes/upload.rb | 11 +- iso/module.mk | 4 +- scripts/release/openstack-essex.json | 804 +++++++++++++++++++++++++++ test/helpers.py | 10 +- test/integration/test_node.py | 28 + 7 files changed, 920 insertions(+), 23 deletions(-) create mode 100644 scripts/release/openstack-essex.json diff --git a/.gitignore b/.gitignore index e74084ac8..3c36b772b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ # services' runtime files *.log *.pid -*.json # Vagrant housekeeping file /.vagrant diff --git a/bin/agent b/bin/agent index a54288a7d..26d9d05f0 100755 --- a/bin/agent +++ b/bin/agent @@ -10,22 +10,41 @@ require 'httpclient' require 'logger' require 'optparse' +module NodeAgentConfig + extend self + + attr_accessor :api + + def define + yield self + end +end + class NodeAgent - def initialize(logger) + def initialize(logger, config=nil) @logger = logger @api_default_address = "localhost" @api_default_port = "8000" - begin - cmdline = ::File.read("/proc/cmdline") - api_ip = cmdline.match(/\burl=http:\/\/((\d{1,3}\.){3}\d{1,3})/)[1] - @logger.info("Found admin node IP address in kernel cmdline: #{api_ip}") - rescue - @logger.error("Can't get API url from /proc/cmdline. Will use localhost.") - api_ip = "127.0.0.1" + + if not config.nil? + if not config.api.nil? + @api_url = config.api + end + end + + if not @api_url + begin + cmdline = ::File.read("/proc/cmdline") + api_ip = cmdline.match(/\burl=http:\/\/((\d{1,3}\.){3}\d{1,3})/)[1] + @logger.info("Found admin node IP address in kernel cmdline: #{api_ip}") + rescue + @logger.error("Can't get API url from /proc/cmdline. Will use localhost.") + api_ip = "127.0.0.1" + end + @api_url = "http://#{api_ip}:#{@api_default_port}/api" end - @api_url = "http://#{api_ip}:#{@api_default_port}/api" @os = Ohai::System.new() @os.all_plugins @@ -125,10 +144,24 @@ class NodeAgent :os_platform => @os[:platform], :meta => _metadata } - res[:status] = "discover" if File.exist?("/opt/nailgun/system_type") + + res[:status] = @node_state if @node_state res end + def update_state + @node_state = nil + if File.exist?("/opt/nailgun/system_type") + fl = File.open("/opt/nailgun/system_type", "r") + system_type = fl.readline.rstrip + @node_state = "discover" if system_type == "bootstrap" + else + fl = File.open("/opt/nailgun/system_type", "w") + fl.puts("target") + @node_state = "ready" + end + end + end @@ -136,8 +169,38 @@ logger = Logger.new(STDOUT) logger.level = Logger::DEBUG -agent = NodeAgent.new(logger) +options = {} +optparser = OptionParser.new do |opts| + opts.banner = "Usage: #{__FILE__} [options]" + + opts.on( '-h', '--help', 'Display this screen' ) do + puts opts + exit + end + + opts.on("-c", "--config CONFIG", "Config file") do |config_file| + options[:config_file] = config_file + end + +end + +optparser.parse! + +if options[:config_file].nil? + options[:config_file] = "/etc/nailgun-agent/config.rb" +end + begin + logger.info("Trying to load agent config #{options[:config_file]}") + load options[:config_file] +rescue LoadError + logger.error("Error occured while loading agent config") +end + + +agent = NodeAgent.new(logger, NodeAgentConfig) +begin + agent.update_state res = agent.post if res.status == 409: agent.put diff --git a/cookbooks/nailgun/recipes/upload.rb b/cookbooks/nailgun/recipes/upload.rb index 11dadf139..6abda8d74 100644 --- a/cookbooks/nailgun/recipes/upload.rb +++ b/cookbooks/nailgun/recipes/upload.rb @@ -1,8 +1,5 @@ -releases = Dir.glob("#{node[:nailgun][:root]}/os-cookbooks/releases/*.json") -releases.each do |rls| - bash "Bash script for release creation #{rls}" do - code <<-EOH - #{node[:nailgun][:root]}/bin/create_release -f "#{rls}" - EOH - end +bash "Bash script for release creation #{rls}" do + code <<-EOH + #{node[:nailgun][:root]}/bin/create_release -f ""#{node[:nailgun][:root]}/openstack-essex.json"" + EOH end diff --git a/iso/module.mk b/iso/module.mk index a691e9ebd..62452227a 100644 --- a/iso/module.mk +++ b/iso/module.mk @@ -135,7 +135,7 @@ $/isoroot.done: \ $(addprefix $(ISOROOT)/nailgun/bin/,create_release agent) \ $(addprefix $(ISOROOT)/nailgun/solo/,solo.rb solo.json) \ $(addprefix $(ISOROOT)/nailgun/cookbooks/,$(call find-files,cookbooks)) \ - $(addprefix $(ISOROOT)/nailgun/os-cookbooks/,$(call find-files,cooks)) \ + $(addprefix $(ISOROOT)/nailgun/,openstack-essex.json) \ $/isoroot-gems.done \ $(ISOROOT)/eggs \ $(addprefix $(ISOROOT)/eggs/,$(call find-files,$(BINARIES_DIR)/eggs)) \ @@ -332,7 +332,7 @@ $(ISOROOT)/sync/%: iso/sync/% ; $(ACTION.COPY) $(ISOROOT)/indices/override.$(UBUNTU_RELEASE).extra.main: $/override.$(UBUNTU_RELEASE).extra.main ; $(ACTION.COPY) $(ISOROOT)/indices/%: $(BINARIES_DIR)/ubuntu/$(UBUNTU_RELEASE)/indices/% ; $(ACTION.COPY) $(ISOROOT)/nailgun/cookbooks/%: cookbooks/% ; $(ACTION.COPY) -$(ISOROOT)/nailgun/os-cookbooks/%: cooks/% ; $(ACTION.COPY) +$(ISOROOT)/nailgun/openstack-essex.json: scripts/release/openstack-essex.json ; $(ACTION.COPY) $(ISOROOT)/nailgun/solo/%: iso/solo/% ; $(ACTION.COPY) $(ISOROOT)/nailgun/bin/%: bin/% ; $(ACTION.COPY) $(ISOROOT)/nailgun/%: nailgun/% ; $(ACTION.COPY) diff --git a/scripts/release/openstack-essex.json b/scripts/release/openstack-essex.json new file mode 100644 index 000000000..b4639da99 --- /dev/null +++ b/scripts/release/openstack-essex.json @@ -0,0 +1,804 @@ +{ + "name": "OpenStack Essex Release", + "version": "0.1.0", + "description": "Alpha release", + "networks_metadata": [ + {"name": "floating", "access": "public"}, + {"name": "public", "access": "public"}, + {"name": "management", "access": "private10"}, + {"name": "storage", "access": "private172"} + ], + + "roles": [ + { + "name": "infrastructure", + "components": [ + "infrastructure" + ] + }, + { + "name": "controller", + "components": [ + "mysql_server", + "mysql_client", + "rabbitmq", + "keystone", + "glance", + "nova", + "horizon" + ] + }, + { + "name": "compute", + "components": [ + "mysql_client", + "nova_compute" + ] + }, + { + "name": "controller-compute-both", + "components": [ + "mysql_server", + "mysql_client", + "rabbitmq", + "keystone", + "glance", + "nova_both", + "horizon" + ] + } + ], + + "components": [ + { + "name": "infrastructure", + "deploy": { + "driver": "chef-solo", + "driver_args": { + "run_list": [ + "recipe[network::create_interfaces@0.0.2]", + "recipe[firewall::disable@0.8.1]", + "recipe[ntp::default@1.1.2]" + ] + } + }, + "provides": ["infrastructure_endpoint"], + "requires": [] + }, + { + "name": "mysql_server", + "deploy": { + "driver": "chef-solo", + "driver_args": { + "run_list": [ + "recipe[mysql::server@0.1.0]" + ], + "cooks":[ + {"name": "mysql", "version": "0.1.0"}, + {"name": "database", "version": "1.2.0"}, + {"name": "chef-resource-groups", "version": "0.1.0"} + ] + } + }, + "provides": [ + "mysql_server_endpoint", + "mysql_db_maker_endpoint", + "mysql_keystone_endpoint", + "mysql_glance_endpoint", + "mysql_horizon_endpoint", + "mysql_nova_endpoint" + ], + "requires": ["infrastructure_endpoint"] + }, + { + "name": "mysql_client", + "deploy": { + "driver": "chef-solo", + "driver_args": { + "run_list": [ + "recipe[mysql::client@0.1.0]" + ], + "cooks":[ + {"name": "mysql", "version": "0.1.0"}, + {"name": "database", "version": "1.2.0"}, + {"name": "chef-resource-groups", "version": "0.1.0"} + ] + } + }, + "provides": [], + "requires": ["infrastructure_endpoint"] + }, + { + "name": "rabbitmq", + "deploy": { + "driver": "chef-solo", + "driver_args": { + "run_list": [ + "recipe[rabbitmq::default@0.1.0]" + ], + "cooks":[ + {"name": "rabbitmq", "version": "0.1.0"}, + {"name": "database", "version": "1.2.0"}, + {"name": "chef-resource-groups", "version": "0.1.0"} + ] + } + }, + "provides": ["rabbitmq_endpoint"], + "requires": ["infrastructure_endpoint"] + }, + { + "name": "keystone", + "deploy": { + "driver": "chef-solo", + "driver_args": { + "run_list": [ + "recipe[keystone::server@0.0.1]" + ], + "cooks":[ + {"name": "keystone", "version": "0.0.1"}, + {"name": "database", "version": "1.2.0"}, + {"name": "chef-resource-groups", "version": "0.1.0"} + ] + } + }, + "provides": ["keystone_endpoint"], + "requires": [ + "infrastructure_endpoint", + "mysql_server_endpoint", + "mysql_db_maker_endpoint", + "mysql_keystone_endpoint" + ] + }, + { + "name": "glance", + "deploy": { + "driver": "chef-solo", + "driver_args": { + "run_list": [ + "recipe[glance::api@0.0.1]", + "recipe[glance::registry@0.0.1]" + ], + "cooks":[ + {"name": "glance", "version": "0.0.1"}, + {"name": "database", "version": "1.2.0"}, + {"name": "chef-resource-groups", "version": "0.1.0"} + ] + } + }, + "provides": ["glance_endpoint"], + "requires": [ + "infrastructure_endpoint", + "mysql_server_endpoint", + "mysql_db_maker_endpoint", + "mysql_glance_endpoint", + "rabbitmq_endpoint", + "keystone_endpoint" + ] + }, + { + "name": "nova", + "deploy": { + "driver": "chef-solo", + "driver_args": { + "run_list": [ + "recipe[nova::api@0.0.1]", + "recipe[nova::scheduler@0.0.1]", + "recipe[nova::project@0.0.1]", + "recipe[nova::vncproxy@0.0.1]", + "recipe[nova::volume@0.0.1]" + ], + "cooks":[ + {"name": "nova", "version": "0.0.1"}, + {"name": "database", "version": "1.2.0"}, + {"name": "chef-resource-groups", "version": "0.1.0"} + ] + } + }, + "provides": [ + "nova_endpoint", + "nova_api_endpoint", + "nova_vnc_endpoint", + "nova_volume_endpoint" + ], + "requires": [ + "infrastructure_endpoint", + "mysql_server_endpoint", + "mysql_db_maker_endpoint", + "mysql_nova_endpoint", + "keystone_endpoint", + "rabbitmq_endpoint", + "glance_endpoint" + ] + }, + { + "name": "nova_compute", + "deploy": { + "driver": "chef-solo", + "driver_args": { + "run_list": [ + "recipe[nova::compute@0.0.1]" + ], + "cooks":[ + {"name": "nova", "version": "0.0.1"}, + {"name": "database", "version": "1.2.0"}, + {"name": "chef-resource-groups", "version": "0.1.0"} + ] + } + }, + "provides": [ + "nova_endpoint", + "nova_api_endpoint" + ], + "requires": [ + "infrastructure_endpoint", + "mysql_server_endpoint", + "mysql_nova_endpoint", + "keystone_endpoint", + "rabbitmq_endpoint", + "glance_endpoint" + ] + }, + { + "name": "nova_both", + "deploy": { + "driver": "chef-solo", + "driver_args": { + "run_list": [ + "recipe[nova::api@0.0.1]", + "recipe[nova::scheduler@0.0.1]", + "recipe[nova::project@0.0.1]", + "recipe[nova::vncproxy@0.0.1]", + "recipe[nova::volume@0.0.1]", + "recipe[nova::compute@0.0.1]" + ], + "cooks":[ + {"name": "nova", "version": "0.0.1"}, + {"name": "database", "version": "1.2.0"}, + {"name": "chef-resource-groups", "version": "0.1.0"} + ] + } + }, + "provides": [ + "nova_endpoint", + "nova_api_endpoint", + "nova_vnc_endpoint", + "nova_volume_endpoint" + ], + "requires": [ + "infrastructure_endpoint", + "mysql_server_endpoint", + "mysql_db_maker_endpoint", + "mysql_nova_endpoint", + "keystone_endpoint", + "rabbitmq_endpoint", + "glance_endpoint" + ] + }, + { + "name": "horizon", + "deploy": { + "driver": "chef-solo", + "driver_args": { + "run_list": [ + "recipe[horizon::server@0.0.1]" + ], + "cooks":[ + {"name": "horizon", "version": "0.0.1"}, + {"name": "database", "version": "1.2.0"}, + {"name": "chef-resource-groups", "version": "0.1.0"} + ] + } + }, + "provides": [ + "horizon_endpoint" + ], + "requires": [ + "infrastructure_endpoint", + "mysql_server_endpoint", + "mysql_db_maker_endpoint", + "mysql_horizon_endpoint", + "keystone_endpoint", + "glance_endpoint", + "nova_api_endpoint", + "nova_volume_endpoint" + ] + } + ], + + "points": [ + { + "name": "infrastructure_endpoint", + "scheme": { + "nailgun_address": { + "generator": "generator_ip_repo", + "generator_args": "", + "attribute": "repo.address" + }, + "admin_address": { + "generator": "generator_ip", + "generator_args": "admin", + "attribute": "networks.admin.address" + }, + "admin_netmask": { + "generator": "generator_netmask", + "generator_args": "admin", + "attribute": "networks.admin.netmask" + }, + "admin_device": { + "generator": "generator_transparent", + "generator_args": "eth0:0", + "attribute": "networks.admin.device" + }, + "public_address": { + "generator": "generator_ip", + "generator_args": "public", + "attribute": "networks.public.address" + }, + "public_netmask": { + "generator": "generator_netmask", + "generator_args": "public", + "attribute": "networks.public.netmask" + }, + "public_device": { + "generator": "generator_transparent", + "generator_args": "eth0:1", + "attribute": "networks.public.device" + }, + "floating_address": { + "generator": "generator_ip", + "generator_args": "floating", + "attribute": "networks.floating.address" + }, + "floating_netmask": { + "generator": "generator_netmask", + "generator_args": "floating", + "attribute": "networks.floating.netmask" + }, + "floating_device": { + "generator": "generator_transparent", + "generator_args": "eth0:2", + "attribute": "networks.floating.device" + }, + "storage_address": { + "generator": "generator_ip", + "generator_args": "storage", + "attribute": "networks.storage.address" + }, + "storage_netmask": { + "generator": "generator_netmask", + "generator_args": "storage", + "attribute": "networks.storage.netmask" + }, + "storage_device": { + "generator": "generator_transparent", + "generator_args": "eth0:3", + "attribute": "networks.storage.device" + } + } + }, + { + "name": "mysql_server_endpoint", + "scheme": { + "host": { + "generator": "generator_ip", + "generator_args": "admin", + "attribute": ["mysql.host", "mysql.admin.host"] + }, + "port": { + "generator": "generator_transparent", + "generator_args": 3306, + "attribute": ["mysql.port", "mysql.admin.port"] + }, + "url": { + "generator": "generator_url", + "generator_args": { + "protocol": "mysql", + "network": "admin", + "port": "3306" + }, + "attribute": "mysql.url" + } + } + }, + { + "name": "mysql_db_maker_endpoint", + "scheme": { + "username": { + "generator": "generator_transparent", + "generator_args": "db_maker", + "attribute": ["mysql.username", "mysql.admin.username"] + }, + "password": { + "generator": "generator_password", + "generator_args": "8", + "attribute": [ + "mysql.password", + "mysql.admin.password", + "mysql.db_maker_password" + ] + } + } + }, + { + "name": "mysql_keystone_endpoint", + "scheme": { + "password": { + "generator": "generator_password", + "generator_args": "8", + "attribute": "keystone.db.password" + } + } + }, + { + "name": "mysql_nova_endpoint", + "scheme": { + "password": { + "generator": "generator_password", + "generator_args": "8", + "attribute": "nova.db.password" + } + + } + }, + { + "name": "mysql_horizon_endpoint", + "scheme": { + "password": { + "generator": "generator_password", + "generator_args": "8", + "attribute": "horizon.db.password" + }, + "dbname": { + "generator": "generator_transparent", + "generator_args": "horizon", + "attribute": "horizon.db.name" + }, + "username": { + "generator": "generator_transparent", + "generator_args": "horizon", + "attribute": "horizon.db.username" + } + } + }, + { + "name": "mysql_glance_endpoint", + "scheme": { + "password": { + "generator": "generator_password", + "generator_args": "8", + "attribute": "glance.db.password" + } + + } + }, + { + "name": "rabbitmq_endpoint", + "scheme": { + "host": { + "generator": "generator_ip", + "generator_args": "admin", + "attribute": [ + "rabbitmq.admin.host", + "rabbitmq.host" + ] + }, + "port": { + "generator": "generator_transparent", + "generator_args": "5672", + "attribute": [ + "rabbitmq.admin.port", + "rabbitmq.port" + ] + }, + "user": { + "generator": "generator_transparent", + "generator_args": "guest", + "attribute": "nova.rabbitmq.password" + } + } + }, + { + "name": "keystone_endpoint", + "scheme": { + "admin_tenant": { + "generator": "generator_transparent", + "generator_args": "admin", + "attribute": "keystone.admin_tenant" + }, + "admin_user": { + "generator": "generator_transparent", + "generator_args": "admin", + "attribute": "keystone.admin_user" + }, + "admin_password": { + "generator": "generator_password", + "generator_args": "8", + "attribute": "keystone.admin_password" + }, + "admin_role": { + "generator": "generator_transparent", + "generator_args": "admin", + "attribute": "keystone.admin_role" + }, + "admin_token": { + "generator": "generator_password", + "generator_args": "8", + "attribute": "keystone.admin_token" + }, + "service_tenant": { + "generator": "generator_transparent", + "generator_args": "service", + "attribute": "keystone.admin_token" + }, + "glance_user": { + "generator": "generator_transparent", + "generator_args": "glance", + "attribute": "glance.keystone.service_user" + }, + "glance_password": { + "generator": "generator_password", + "generator_args": "8", + "attribute": "glance.keystone.service_password" + }, + "horizon_user": { + "generator": "generator_transparent", + "generator_args": "horizon", + "attribute": "horizon.keystone.service_user" + }, + "horizon_password": { + "generator": "generator_password", + "generator_args": "8", + "attribute": "horizon.keystone.service_password" + }, + "nova_user": { + "generator": "generator_transparent", + "generator_args": "nova", + "attribute": "nova.keystone.service_user" + }, + "nova_password": { + "generator": "generator_password", + "generator_args": "8", + "attribute": "nova.keystone.service_password" + }, + "volume_user": { + "generator": "generator_transparent", + "generator_args": "volume", + "attribute": "volume.keystone.service_user" + }, + "volume_password": { + "generator": "generator_password", + "generator_args": "8", + "attribute": "volume.keystone.service_password" + }, + "admin_host": { + "generator": "generator_ip", + "generator_args": "admin", + "attribute": "keystone.admin.host" + }, + "public_host": { + "generator": "generator_ip", + "generator_args": "public", + "attribute": "keystone.public.host" + }, + "admin_port": { + "generator": "generator_transparent", + "generator_args": "35357", + "attribute": [ + "keystone.admin.admin_port", + "keystone.public.admin_port" + ] + }, + "service_port": { + "generator": "generator_transparent", + "generator_args": "5000", + "attribute": [ + "keystone.admin.service_port", + "keystone.public.service_port" + ] + }, + "admin_url": { + "generator": "generator_url", + "generator_args": { + "protocol": "http", + "network": "admin", + "port": "35357" + }, + "attribute": "keystone.admin_url" + }, + "public_url": { + "generator": "generator_url", + "generator_args": { + "protocol": "http", + "network": "public", + "port": "5000" + }, + "attribute": "keystone.public_url" + }, + "internal_url": { + "generator": "generator_url", + "generator_args": { + "protocol": "http", + "network": "admin", + "port": "5000" + }, + "attribute": "keystone.internal_url" + } + } + }, + { + "name": "glance_endpoint", + "scheme": { + "admin_host": { + "generator": "generator_ip", + "generator_args": "admin", + "attribute": [ + "glance.api.admin.host", + "glance.registry.admin.host", + "glance.registry.bindhost" + ] + }, + "public_host": { + "generator": "generator_ip", + "generator_args": "public", + "attribute": [ + "glance.api.public.host", + "glance.registry.public.host" + ] + }, + "api_port": { + "generator": "generator_transparent", + "generator_args": "9292", + "attribute": [ + "glance.api.admin.port", + "glance.api.public.port" + ] + }, + "registry_port": { + "generator": "generator_transparent", + "generator_args": "9191", + "attribute": [ + "glance.registry.admin.port", + "glance.registry.public.port" + ] + }, + "api_public_url": { + "generator": "generator_url", + "generator_args": { + "protocol": "http", + "network": "public", + "port": "9292" + }, + "attribute": "glance.api.public.url" + }, + "api_admin_url": { + "generator": "generator_url", + "generator_args": { + "protocol": "http", + "network": "admin", + "port": "9292" + }, + "attribute": "glance.api.admin.url" + }, + "registry_public_url": { + "generator": "generator_url", + "generator_args": { + "protocol": "http", + "network": "public", + "port": "9191" + }, + "attribute": "glance.registry.public.url" + }, + "registry_admin_url": { + "generator": "generator_url", + "generator_args": { + "protocol": "http", + "network": "admin", + "port": "9191" + }, + "attribute": "glance.registry.admin.url" + } + } + }, + { + "name": "nova_api_endpoint", + "scheme": { + "admin_host": { + "generator": "generator_ip", + "generator_args": "admin", + "attribute": "nova_api.admin.host" + }, + "public_host": { + "generator": "generator_ip", + "generator_args": "public", + "attribute": "nova_api.public.host" + } + } + }, + { + "name": "nova_vnc_endpoint", + "scheme": { + "admin_host": { + "generator": "generator_ip", + "generator_args": "admin", + "attribute": "nova_vnc.admin.host" + }, + "public_host": { + "generator": "generator_ip", + "generator_args": "public", + "attribute": "nova_vnc.public.host" + } + } + }, + { + "name": "nova_volume_endpoint", + "scheme": { + "admin_host": { + "generator": "generator_ip", + "generator_args": "admin", + "attribute": "volume.admin.host" + }, + "public_host": { + "generator": "generator_ip", + "generator_args": "public", + "attribute": "volume.public.host" + } + } + }, + { + "name": "nova_endpoint", + "scheme": { + "admin_host": { + "generator": "generator_ip", + "generator_args": "admin", + "attribute": "nova.admin.host" + }, + "public_host": { + "generator": "generator_ip", + "generator_args": "public", + "attribute": "nova.public.host" + }, + "fixed_range": { + "generator": "generator_transparent", + "generator_args": "10.0.6.0/24", + "attribute": "nova.network.fixed_range" + }, + "floating_range": { + "generator": "generator_transparent", + "generator_args": "192.168.101.0/24", + "attribute": "nova.network.floating_range" + }, + "public_interface": { + "generator": "generator_transparent", + "generator_args": "eth0", + "attribute": "nova.network.public_interface" + }, + "vlan_interface": { + "generator": "generator_transparent", + "generator_args": "eth1", + "attribute": "nova.network.vlan_interface" + }, + "vlan": { + "generator": "generator_transparent", + "generator_args": "106", + "attribute": "nova.network.vlan" + }, + "ha_enabled": { + "generator": "generator_transparent", + "generator_args": "true", + "attribute": "nova.network.ha_enabled" + } + } + }, + { + "name": "horizon_endpoint", + "scheme": { + "admin_host": { + "generator": "generator_ip", + "generator_args": "admin", + "attribute": "horizon.admin.host" + } + } + } + + ] +} \ No newline at end of file diff --git a/test/helpers.py b/test/helpers.py index 2320c3923..362cf4d73 100644 --- a/test/helpers.py +++ b/test/helpers.py @@ -3,7 +3,6 @@ import urllib2 import logging import posixpath import json -import cStringIO import paramiko @@ -36,7 +35,14 @@ class HTTPClient(object): try: res = self.opener.open(req) except urllib2.HTTPError as err: - res = cStringIO.StringIO(str(err)) + res = type( + 'HTTPError', + (object,), + { + 'read': lambda s: str(err), + 'getcode': lambda s: err.code + } + )() return res diff --git a/test/integration/test_node.py b/test/integration/test_node.py index 13bf44377..6fe8b415f 100644 --- a/test/integration/test_node.py +++ b/test/integration/test_node.py @@ -60,6 +60,30 @@ class TestNode(Base): self._update_nodes_in_cluster(cluster_id, nodes) self._launch_provisioning(cluster_id) + timer = time.time() + timeout = 1800 + ready = False + while not ready: + try: + for node_id in nodes: + node = json.loads(self.client.get( + "/api/nodes/%s/" % node_id + ).read()) + if node["status"] == 'provisioning': + logging.info("Installation in progress...") + raise StillPendingException() + elif node["status"] == 'error': + raise Exception( + "Installation failed!" + ) + elif node["status"] == 'ready': + logging.info("Installation complete!") + ready = True + except StillPendingException: + if (time.time() - timer) > timeout: + raise Exception("Installation timeout expired!") + time.sleep(30) + #if node["status"] == "discover": #logging.info("Node booted with bootstrap image.") #elif node["status"] == "ready": @@ -138,6 +162,10 @@ class TestNode(Base): #slave_client.disconnect() def _launch_provisioning(self, cluster_id): + logging.info( + "Launching provisioning on cluster %d", + cluster_id + ) changes = self.client.put( "/api/clusters/%d/changes/" % cluster_id )