agent fix and installation test

This commit is contained in:
Nikolay Markov 2012-09-20 17:44:55 +04:00
parent 5a2eb6468d
commit d9c38b9fb7
7 changed files with 920 additions and 23 deletions

1
.gitignore vendored
View File

@ -7,7 +7,6 @@
# services' runtime files
*.log
*.pid
*.json
# Vagrant housekeeping file
/.vagrant

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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"
}
}
}
]
}

View File

@ -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

View File

@ -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
)