installs packages, add mysql relation

This commit is contained in:
yolanda.robla@canonical.com 2013-11-21 10:41:44 +01:00
parent e67b892874
commit 7b845f0704
11 changed files with 262 additions and 103 deletions

View File

@ -5,4 +5,7 @@ include:
- fetch
- contrib.openstack|inc=*
- contrib.storage
- contrib.hahelpers:
- apache
- cluster
- payload.execd

View File

@ -15,7 +15,7 @@ options:
provide a later version of OpenStack will trigger a software
upgrade.
rabbit-user:
default: nova
default: heat
type: string
description: Username used to access rabbitmq queue
rabbit-vhost:
@ -23,10 +23,10 @@ options:
type: string
decsription: Rabbitmq vhost
database-user:
default: nova
default: heat
type: string
description: Username for database access
database:
default: nova
default: heat
type: string
description: Database name

View File

@ -0,0 +1,58 @@
#
# Copyright 2012 Canonical Ltd.
#
# This file is sourced from lp:openstack-charm-helpers
#
# Authors:
# James Page <james.page@ubuntu.com>
# Adam Gandelman <adamg@ubuntu.com>
#
import subprocess
from charmhelpers.core.hookenv import (
config as config_get,
relation_get,
relation_ids,
related_units as relation_list,
log,
INFO,
)
def get_cert():
cert = config_get('ssl_cert')
key = config_get('ssl_key')
if not (cert and key):
log("Inspecting identity-service relations for SSL certificate.",
level=INFO)
cert = key = None
for r_id in relation_ids('identity-service'):
for unit in relation_list(r_id):
if not cert:
cert = relation_get('ssl_cert',
rid=r_id, unit=unit)
if not key:
key = relation_get('ssl_key',
rid=r_id, unit=unit)
return (cert, key)
def get_ca_cert():
ca_cert = None
log("Inspecting identity-service relations for CA SSL certificate.",
level=INFO)
for r_id in relation_ids('identity-service'):
for unit in relation_list(r_id):
if not ca_cert:
ca_cert = relation_get('ca_cert',
rid=r_id, unit=unit)
return ca_cert
def install_ca_cert(ca_cert):
if ca_cert:
with open('/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt',
'w') as crt:
crt.write(ca_cert)
subprocess.check_call(['update-ca-certificates', '--fresh'])

View File

@ -0,0 +1,183 @@
#
# Copyright 2012 Canonical Ltd.
#
# Authors:
# James Page <james.page@ubuntu.com>
# Adam Gandelman <adamg@ubuntu.com>
#
import subprocess
import os
from socket import gethostname as get_unit_hostname
from charmhelpers.core.hookenv import (
log,
relation_ids,
related_units as relation_list,
relation_get,
config as config_get,
INFO,
ERROR,
unit_get,
)
class HAIncompleteConfig(Exception):
pass
def is_clustered():
for r_id in (relation_ids('ha') or []):
for unit in (relation_list(r_id) or []):
clustered = relation_get('clustered',
rid=r_id,
unit=unit)
if clustered:
return True
return False
def is_leader(resource):
cmd = [
"crm", "resource",
"show", resource
]
try:
status = subprocess.check_output(cmd)
except subprocess.CalledProcessError:
return False
else:
if get_unit_hostname() in status:
return True
else:
return False
def peer_units():
peers = []
for r_id in (relation_ids('cluster') or []):
for unit in (relation_list(r_id) or []):
peers.append(unit)
return peers
def oldest_peer(peers):
local_unit_no = int(os.getenv('JUJU_UNIT_NAME').split('/')[1])
for peer in peers:
remote_unit_no = int(peer.split('/')[1])
if remote_unit_no < local_unit_no:
return False
return True
def eligible_leader(resource):
if is_clustered():
if not is_leader(resource):
log('Deferring action to CRM leader.', level=INFO)
return False
else:
peers = peer_units()
if peers and not oldest_peer(peers):
log('Deferring action to oldest service unit.', level=INFO)
return False
return True
def https():
'''
Determines whether enough data has been provided in configuration
or relation data to configure HTTPS
.
returns: boolean
'''
if config_get('use-https') == "yes":
return True
if config_get('ssl_cert') and config_get('ssl_key'):
return True
for r_id in relation_ids('identity-service'):
for unit in relation_list(r_id):
rel_state = [
relation_get('https_keystone', rid=r_id, unit=unit),
relation_get('ssl_cert', rid=r_id, unit=unit),
relation_get('ssl_key', rid=r_id, unit=unit),
relation_get('ca_cert', rid=r_id, unit=unit),
]
# NOTE: works around (LP: #1203241)
if (None not in rel_state) and ('' not in rel_state):
return True
return False
def determine_api_port(public_port):
'''
Determine correct API server listening port based on
existence of HTTPS reverse proxy and/or haproxy.
public_port: int: standard public port for given service
returns: int: the correct listening port for the API service
'''
i = 0
if len(peer_units()) > 0 or is_clustered():
i += 1
if https():
i += 1
return public_port - (i * 10)
def determine_haproxy_port(public_port):
'''
Description: Determine correct proxy listening port based on public IP +
existence of HTTPS reverse proxy.
public_port: int: standard public port for given service
returns: int: the correct listening port for the HAProxy service
'''
i = 0
if https():
i += 1
return public_port - (i * 10)
def get_hacluster_config():
'''
Obtains all relevant configuration from charm configuration required
for initiating a relation to hacluster:
ha-bindiface, ha-mcastport, vip, vip_iface, vip_cidr
returns: dict: A dict containing settings keyed by setting name.
raises: HAIncompleteConfig if settings are missing.
'''
settings = ['ha-bindiface', 'ha-mcastport', 'vip', 'vip_iface', 'vip_cidr']
conf = {}
for setting in settings:
conf[setting] = config_get(setting)
missing = []
[missing.append(s) for s, v in conf.iteritems() if v is None]
if missing:
log('Insufficient config data to configure hacluster.', level=ERROR)
raise HAIncompleteConfig
return conf
def canonical_url(configs, vip_setting='vip'):
'''
Returns the correct HTTP URL to this host given the state of HTTPS
configuration and hacluster.
:configs : OSTemplateRenderer: A config tempating object to inspect for
a complete https context.
:vip_setting: str: Setting in charm config that specifies
VIP address.
'''
scheme = 'http'
if 'https' in configs.complete_contexts():
scheme = 'https'
if is_clustered():
addr = config_get(vip_setting)
else:
addr = unit_get('private-address')
return '%s://%s' % (scheme, addr)

View File

@ -210,6 +210,7 @@ def import_key(keyid):
def configure_installation_source(rel):
juju_log("in configure %s" % rel)
'''Configure apt installation source.'''
if rel == 'distro':
return
@ -219,6 +220,7 @@ def configure_installation_source(rel):
f.write(DISTRO_PROPOSED % ubuntu_rel)
elif rel[:4] == "ppa:":
src = rel
juju_log("add apt %s" % src)
subprocess.check_call(["add-apt-repository", "-y", src])
elif rel[:3] == "deb":
l = len(rel.split('|'))

View File

@ -15,7 +15,7 @@ class IdentityServiceContext(context.IdentityServiceContext):
return
# the ec2 api needs to know the location of the keystone ec2
# tokens endpoint, set in nova.conf
# tokens endpoint, set in heat.conf
ec2_tokens = 'http://%s:%s/v2.0/ec2tokens' % (ctxt['service_host'],
ctxt['service_port'])
ctxt['keystone_ec2_url'] = ec2_tokens

View File

@ -40,7 +40,6 @@ from charmhelpers.fetch import (
from charmhelpers.contrib.openstack.utils import (
configure_installation_source,
openstack_upgrade_available,
)
from utils import (
@ -49,13 +48,8 @@ from utils import (
determine_endpoints,
determine_packages,
determine_ports,
do_openstack_upgrade,
keystone_ca_cert_b64,
save_script_rc,
ssh_compute_add,
ssh_compute_remove,
ssh_known_hosts_b64,
ssh_authorized_keys_b64,
register_configs,
restart_map,
HEAT_CONF
@ -106,9 +100,9 @@ def amqp_changed():
@hooks.hook('shared-db-relation-joined')
def db_joined():
relation_set(nova_database=config('database'),
nova_username=config('database-user'),
nova_hostname=unit_get('private-address'))
relation_set(heat_database=config('database'),
heat_username=config('database-user'),
heat_hostname=unit_get('private-address'))
@hooks.hook('shared-db-relation-changed')
@ -118,6 +112,7 @@ def db_changed():
log('shared-db relation incomplete. Peer not ready?')
return
CONFIGS.write(HEAT_CONF)
check_call(['heat-manage', 'db_sync'])
@hooks.hook('identity-service-relation-joined')

View File

@ -66,7 +66,7 @@ BASE_RESOURCE_MAP = OrderedDict([
(HEAT_CONF, {
'services': BASE_SERVICES,
'contexts': [context.AMQPContext(),
context.SharedDBContext(relation_prefix='nova'),
context.SharedDBContext(relation_prefix='heat'),
context.OSConfigFlagContext(),
heat_context.IdentityServiceContext()]
}),

View File

@ -2,9 +2,9 @@ name: heat
summary: OpenStack orchestration engine
maintainer: Yolanda Robla <yolanda.robla@canonical.com>
description: |
Heat is the main project in the OpenStack Orchestration program. It implements an
orchestration engine to launch multiple composite cloud applications based on
templates in the form of text files that can be treated like code.
Heat is the main project in the OpenStack Orchestration program. It implements an
orchestration engine to launch multiple composite cloud applications based on
templates in the form of text files that can be treated like code.
categories:
- openstack
provides:

View File

@ -15,63 +15,11 @@ environment_dir=/etc/heat/environment.d
# (string value)
deferred_auth_method=password
# Subset of trustor roles to be delegated to heat (list value)
trusts_delegated_roles=heat_stack_owner
# Maximum resources allowed per top-level stack. (integer
# value)
max_resources_per_stack=1000
# Maximum number of stacks any one tenant may have active at
# one time. (integer value)
max_stacks_per_tenant=100
# Controls how many events will be pruned whenever a stack's
# events exceed max_events_per_stack. Set this lower to keep
# more events at the expense of more frequent purges. (integer
# value)
event_purge_batch_size=10
# Maximum events that will be available per stack. Older
# events will be deleted when this is reached. Set to 0 for
# unlimited events per stack. (integer value)
max_events_per_stack=1000
# Name of the engine node. This can be an opaque identifier.It
# is not necessarily a hostname, FQDN, or IP address. (string
# value)
host=heat
# seconds between running periodic tasks (integer value)
periodic_interval=60
# URL of the Heat metadata server (string value)
heat_metadata_server_url=
# URL of the Heat waitcondition server (string value)
heat_waitcondition_server_url=
# URL of the Heat cloudwatch server (string value)
heat_watch_server_url=
# Instance connection to cfn/cw API via https (string value)
instance_connection_is_secure=0
# Instance connection to cfn/cw API validate certs if ssl
# (string value)
instance_connection_https_validate_certificates=1
# Keystone role for heat template-defined users (string value)
heat_stack_user_role=heat_stack_user
# Maximum raw byte size of any template. (integer value)
max_template_size=524288
# Maximum depth allowed when using nested stacks. (integer
# value)
max_nested_stack_depth=3
#
# Options defined in heat.common.crypt
#
@ -80,33 +28,6 @@ max_nested_stack_depth=3
# (string value)
auth_encryption_key=notgood but just long enough i think
#
# Options defined in heat.common.wsgi
#
# Maximum raw byte size of JSON request body. Should be larger
# than max_template_size. (integer value)
max_json_body_size=1048576
#
# Options defined in heat.db.api
#
# The backend to use for db (string value)
db_backend=mysql
#
# Options defined in heat.engine.clients
#
# Fully qualified class name to use as a client backend.
# (string value)
cloud_backend=heat.engine.clients.OpenStackClients
{% if rabbitmq_host -%}
rabbit_host = {{ rabbitmq_host }}
rabbit_userid = {{ rabbitmq_user }}
@ -115,15 +36,12 @@ rabbit_virtual_host = {{ rabbitmq_virtual_host }}
rabbit_use_ssl = false
{% endif -%}
{% if database_host -%}
sql_connection = mysql://{{ database_user }}:{{ database_password }}@{{ database_host }}/{{ database }}
{% endif -%}
[database]
#
# Options defined in heat.openstack.common.db.api
#
# The backend to use for db (string value)
backend=mysql
# sql
{% if database_host -%}
connection = mysql://{{ database_user }}:{{ database_password }}@{{ database_host }}/{{ database }}