Making env_rc object oriented and cleaning up it and stack.ini which has more settings than it needs (thus confusing.)

This commit is contained in:
Joshua Harlow 2012-02-17 12:52:38 -08:00
parent 74a4a1ce19
commit ee4b3892bd
5 changed files with 136 additions and 200 deletions

View File

@ -64,9 +64,14 @@ keystone_service_protocol = ${KEYSTONE_SERVICE_PROTOCOL:-http}
# User names (used in init script)
invisible_user = invisible_to_admin
demo_user = demo
admin_user = admin
demo_user = ${KEYSTONE_DEMO_USER:-demo}
admin_user = ${KEYSTONE_ADMIN_USER:-admin}
# The above user names are also the tenant names.
# Nova original used project_id as the *account* that owned resources (servers,
# ip address, ...) With the addition of Keystone we have standardized on the
# term **tenant** as the entity that owns the resources.
[nova]
# Should nova be in verbose mode?
@ -75,35 +80,7 @@ verbose = ${NOVA_VERBOSE:-1}
# Allow the admin api to be accessible?
allow_admin_api = 1
# Nova original used project_id as the *account* that owned resources (servers,
# ip address, ...) With the addition of Keystone we have standardized on the
# term **tenant** as the entity that owns the resources. **novaclient** still
# uses the old deprecated terms project_id. Note that this field should now be
# set to tenant_name, not tenant_id.
#
# Set in the initial keystone setup script!
nova_project_id = ${NOVA_TENANT:-demo}
# In addition to the owning entity (tenant), nova stores the entity performing
# the action as the **user**.
#
# Set in the initial keystone setup script!
nova_username = ${NOVA_USERNAME:-demo}
# With the addition of Keystone, to use an openstack cloud you should
# authenticate against keystone, which returns a **Token** and **Service
# Catalog**. The catalog contains the endpoint for all services the user/tenant
# has access to - including nova, glance, keystone, swift, ... We currently
# recommend using the 2.0 *auth api*.
#
# *NOTE*: Using the 2.0 *auth api* does not mean that compute api is 2.0. We
# will use the 1.1 *compute api*
nova_url = ${NOVA_URL:-http://$(host:ip):5000/v2.0/}
# Currently novaclient needs you to specify the *compute api* version. This
# needs to match the config of your catalog returned by Keystone.
#
# Set in the initial keystone setup script!
# Currently novaclient needs you to specify the *compute api* version.
nova_version = ${NOVA_VERSION:-1.1}
# Which scheduler will nova be running with?
@ -195,36 +172,9 @@ s3_url = ${S3_URL:-http://$(host:ip):3333/services/Cloud}
ec2_user_id = 42
ec2_cert_fn = ~/cert.pm
# Set the ec2 url so nova client works
# Typically like http://localhost:5000/v2.0
# If blank we will generate this.
nova_url = ${NOVA_URL:-$(nova:nova_url)}
# Project id is set in the initial keystone setup script
nova_project_id = ${NOVA_PROJECT_ID:-$(nova:nova_project_id)}
# Region name is set in the initial keystone setup script
nova_region_name = ${NOVA_REGION_NAME:-RegionOne}
# ??
nova_version = ${NOVA_VERSION:-$(nova:nova_version)}
# The NOVA_PASSWORD is taken from the horizon keystone admin password
# Not used (currently)??
nova_cert_fn = ~/cert.pm
# Tenant id/user is set in the initial keystone setup script
os_tenant_name = ${OS_TENANT_NAME:-$(nova:nova_project_id)}
os_username = ${OS_USERNAME:-$(nova:nova_username)}
# The OS_PASSWORD is taken from the horizon keystone admin password
# Set the os auth url so nova, glance and such can work from the command line
# Typically like http://localhost:5000/v2.0
# If blank we will generate this.
os_auth_url = ${OS_AUTH_URL:-$(nova:nova_url)}
[git]
# Compute service git repo

View File

@ -108,8 +108,8 @@ class StackConfigParser(IgnoreMissingConfigParser):
self.pws[key] = value_gotten
return value_gotten
def getdefaulted(self, section, option, default_val):
val = self.get(section, option)
def getdefaulted(self, section, option, default_val, auto_pw=True):
val = self.get(section, option, auto_pw=auto_pw)
if not val:
return default_val
return val

View File

@ -76,9 +76,6 @@ WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS
#config keys we warm up so u won't be prompted later
WARMUP_PWS = ['horizon_keystone_admin', 'service_token']
#ec2 rc filename
EC2RC_FN = 'ec2rc'
class KeystoneUninstaller(comp.PythonUninstallComponent):
def __init__(self, *args, **kargs):
@ -211,8 +208,7 @@ class KeystoneRuntime(comp.PythonRuntime):
LOG.info("Running (%s) command to initialize keystone." % (" ".join(setup_cmd)))
(sysout, _) = sh.execute(*setup_cmd, env_overrides=env, run_as_root=False)
if sysout:
ec2rcfn = self.cfg.getdefaulted("keystone", "ec2_rc_fn", settings.EC2RC_FN)
sh.write_file(ec2rcfn, sysout.strip())
sh.write_file(sh.abspth(settings.EC2RC_FN), sysout.strip())
LOG.debug("Removing (%s) file since we successfully initialized keystone." % (tgt_fn))
sh.unlink(tgt_fn)
@ -268,4 +264,5 @@ def get_shared_params(config):
"v2.0", "", "", ""))
mp['SERVICE_TOKEN'] = config.get("passwords", "service_token")
return mp

View File

@ -15,7 +15,6 @@
# under the License.
from urlparse import urlunparse
import os
import re
import subprocess
@ -23,6 +22,9 @@ from devstack import date
from devstack import env
from devstack import settings
from devstack import shell as sh
from devstack import utils
from devstack.components import keystone
#general extraction cfg keys
CFG_MAKE = {
@ -37,8 +39,6 @@ CFG_MAKE = {
#default ports
EC2_PORT = 8773
S3_PORT = 3333
NOVA_PORT = 5000
OS_AUTH_PORT = 5000
#how we know if a line is an export or if it isn't (simpe edition)
EXP_PAT = re.compile("^\s*export\s+(.*?)=(.*?)$", re.IGNORECASE)
@ -47,26 +47,104 @@ EXP_PAT = re.compile("^\s*export\s+(.*?)=(.*?)$", re.IGNORECASE)
QUOTED_PAT = re.compile(r"^\s*[\"](.*)[\"]\s*$")
def _write_line(text, fh):
fh.write(text)
fh.write(os.linesep)
class RcGenerator(object):
def __init__(self, cfg):
self.cfg = cfg
def _generate_header(self):
lines = list()
lines.append('# Generated on %s' % (date.rcf8222date()))
lines.append("")
return lines
def _write_env(name, value, fh):
if value is None:
return
str_value = str(value)
escaped_val = subprocess.list2cmdline([str_value])
if str_value != escaped_val:
_write_line("export %s=\"%s\"" % (name, escaped_val), fh)
else:
_write_line("export %s=%s" % (name, str_value), fh)
def _make_export(self, export_name, value):
str_value = str(value)
escaped_val = subprocess.list2cmdline([str_value])
full_line = ''
if str_value != escaped_val:
full_line = "export %s=\"%s\"" % (export_name, escaped_val)
else:
full_line = "export %s=%s" % (export_name, str_value)
return [full_line]
def _make_export_cfg(self, export_name, cfg_section_key, default_val=''):
(section, key) = cfg_section_key
value = self.cfg.getdefaulted(section, key, default_val, auto_pw=False)
return self._make_export(export_name, value)
def _generate_extern_inc(fh):
_write_line('# External includes stuff', fh)
def _generate_ec2_env(self):
lines = list()
lines.append('# EC2 and/or S3 stuff')
ip = self.cfg.get('host', 'ip')
lines.extend(self._make_export_cfg('EC2_URL',
('extern', 'ec2_url'),
urlunparse(('http', "%s:%s" % (ip, EC2_PORT), "services/Cloud", '', '', ''))))
lines.extend(self._make_export_cfg('S3_URL',
('extern', 's3_url'),
urlunparse(('http', "%s:%s" % (ip, S3_PORT), "services/Cloud", '', '', ''))))
lines.extend(self._make_export_cfg('EC2_CERT',
('extern', 'ec2_cert_fn')))
lines.extend(self._make_export_cfg('EC2_USER_ID',
('extern', 'ec2_user_id')))
lines.append("")
return lines
extern_tpl = """
def _generate_general(self):
lines = list()
lines.append('# General stuff')
for (out_name, cfg_data) in CFG_MAKE.items():
lines.extend(self._make_export_cfg(out_name, cfg_data))
lines.append("")
return lines
def _generate_lines(self):
lines = list()
lines.extend(self._generate_header())
lines.extend(self._generate_general())
lines.extend(self._generate_ec2_env())
lines.extend(self._generate_nova_env())
lines.extend(self._generate_os_env())
lines.extend(self._generate_extern_inc())
return lines
def generate(self):
lines = self._generate_lines()
return utils.joinlinesep(*lines)
def _generate_os_env(self):
lines = list()
lines.append('# Openstack stuff')
lines.extend(self._make_export_cfg('OS_PASSWORD',
('passwords', 'horizon_keystone_admin')))
key_users = keystone.get_shared_users(self.cfg)
key_ends = keystone.get_shared_params(self.cfg)
lines.extend(self._make_export('OS_TENANT_NAME', key_ends['DEMO_TENANT_NAME']))
lines.extend(self._make_export('OS_USERNAME', key_users['DEMO_USER_NAME']))
lines.extend(self._make_export('OS_AUTH_URL', key_ends['SERVICE_ENDPOINT']))
lines.append("")
return lines
def _generate_nova_env(self):
lines = list()
lines.append('# Nova stuff')
lines.extend(self._make_export_cfg('NOVA_PASSWORD',
('passwords', 'horizon_keystone_admin')))
key_users = keystone.get_shared_users(self.cfg)
key_ends = keystone.get_shared_params(self.cfg)
lines.extend(self._make_export('NOVA_URL', key_ends['SERVICE_ENDPOINT']))
lines.extend(self._make_export('NOVA_PROJECT_ID', key_users['DEMO_TENANT_NAME']))
lines.extend(self._make_export('NOVA_USERNAME', key_users['DEMO_USER_NAME']))
lines.extend(self._make_export_cfg('NOVA_VERSION',
('extern', 'nova_version')))
lines.extend(self._make_export_cfg('NOVA_CERT',
('extern', 'nova_cert_fn')))
lines.append("")
return lines
def _generate_extern_inc(self):
lines = list()
lines.append('# External includes stuff')
extern_tpl = """
# Use stored ec2 env variables
if [ -f "{ec2rc_fn}" ]; then
@ -79,122 +157,31 @@ if [ -f "{localrc_fn}" ]; then
fi
"""
extern_inc = extern_tpl.format(ec2rc_fn=sh.abspth(settings.EC2RC_FN),
extern_inc = extern_tpl.format(ec2rc_fn=sh.abspth(settings.EC2RC_FN),
localrc_fn=sh.abspth(settings.LOCALRC_FN))
fh.write(extern_inc.strip())
_write_line("", fh)
lines.append(extern_inc.strip())
lines.append("")
return lines
def _generate_ec2_env(fh, cfg):
_write_line('# EC2 and/or S3 stuff', fh)
ip = cfg.get('host', 'ip')
class RcLoader(object):
def __init__(self):
pass
ec2_url = cfg.get('extern', 'ec2_url')
if not ec2_url:
ec2_url = urlunparse(('http', "%s:%s" % (ip, EC2_PORT), "services/Cloud", '', '', ''))
_write_env('EC2_URL', ec2_url, fh)
s3_url = cfg.get('extern', 's3_url')
if not s3_url:
s3_url = urlunparse(('http', "%s:%s" % (ip, S3_PORT), "services/Cloud", '', '', ''))
_write_env('S3_URL', s3_url, fh)
ec2_cert = cfg.get('extern', 'ec2_cert_fn')
_write_env('EC2_CERT', ec2_cert, fh)
ec2_uid = cfg.get('extern', 'ec2_user_id')
_write_env('EC2_USER_ID', ec2_uid, fh)
_write_line("", fh)
def _generate_nova_env(fh, cfg):
_write_line('# Nova stuff', fh)
ip = cfg.get('host', 'ip')
hkpw = cfg.get('passwords', 'horizon_keystone_admin', auto_pw=False)
_write_env('NOVA_PASSWORD', hkpw, fh)
nv_url = cfg.get('extern', 'nova_url')
if not nv_url:
nv_url = urlunparse(('http', "%s:%s" % (ip, NOVA_PORT), "v2.0", '', '', ''))
_write_env('NOVA_URL', nv_url, fh)
nv_prj = cfg.get('extern', 'nova_project_id')
_write_env('NOVA_PROJECT_ID', nv_prj, fh)
nv_reg = cfg.get('extern', 'nova_region_name')
_write_env('NOVA_REGION_NAME', nv_reg, fh)
nv_ver = cfg.get('extern', 'nova_version')
_write_env('NOVA_VERSION', nv_ver, fh)
nv_cert = cfg.get("extern", 'nova_cert_fn')
_write_env('NOVA_CERT', nv_cert, fh)
_write_line("", fh)
def _generate_os_env(fh, cfg):
_write_line('# Openstack stuff', fh)
ip = cfg.get('host', 'ip')
hkpw = cfg.get('passwords', 'horizon_keystone_admin', auto_pw=False)
_write_env('OS_PASSWORD', hkpw, fh)
os_ten = cfg.get('extern', 'os_tenant_name')
_write_env('OS_TENANT_NAME', os_ten, fh)
os_uname = cfg.get('extern', 'os_username')
_write_env('OS_USERNAME', os_uname, fh)
os_auth_uri = cfg.get('extern', 'os_auth_url')
if not os_auth_uri:
os_auth_uri = urlunparse(('http', "%s:%s" % (ip, OS_AUTH_PORT), "v2.0", '', '', ''))
_write_env('OS_AUTH_URL', os_auth_uri, fh)
_write_line("", fh)
def _generate_header(fh, cfg):
header = '# Generated on %s' % (date.rcf8222date())
_write_line(header, fh)
_write_line("", fh)
def _generate_general(fh, cfg):
_write_line('# General stuff', fh)
for (out_name, cfg_data) in CFG_MAKE.items():
(section, key) = cfg_data
value = cfg.get(section, key, auto_pw=False)
_write_env(out_name, value, fh)
_write_line("", fh)
def generate_local_rc(fn, cfg):
with open(fn, "w") as fh:
_generate_header(fh, cfg)
_generate_general(fh, cfg)
_generate_ec2_env(fh, cfg)
_generate_nova_env(fh, cfg)
_generate_os_env(fh, cfg)
_generate_extern_inc(fh)
def load_local_rc(fn):
am_set = 0
with open(fn, "r") as fh:
for line in fh:
m = EXP_PAT.search(line)
if m:
key = m.group(1).strip()
value = m.group(2).strip()
#remove inline comment if any
value = value.split("#")[0].strip()
if len(key):
qmtch = QUOTED_PAT.match(value)
if qmtch:
value = qmtch.group(1).decode('string_escape').strip()
env.set(key, value)
am_set += 1
return am_set
def load(self, fn):
am_set = 0
with open(fn, "r") as fh:
for line in fh:
m = EXP_PAT.search(line)
if m:
key = m.group(1).strip()
value = m.group(2).strip()
#remove inline comment if any
value = value.split("#")[0].strip()
if len(key):
qmtch = QUOTED_PAT.match(value)
if qmtch:
value = qmtch.group(1).decode('string_escape').strip()
env.set(key, value)
am_set += 1
return am_set

View File

@ -96,7 +96,7 @@ def _pre_run(action_name, root_dir, pkg_manager, config, component_order, instan
try:
if sh.isfile(rc_fn):
LOG.info("Attempting to load rc file at [%s] which has your environment settings." % (rc_fn))
am_loaded = env_rc.load_local_rc(rc_fn)
am_loaded = env_rc.RcLoader().load(rc_fn)
loaded_env = True
LOG.info("Loaded [%s] settings from rc file [%s]" % (am_loaded, rc_fn))
except IOError:
@ -268,7 +268,9 @@ def _instanciate_components(action_name, components, distro, pkg_manager, config
def _gen_localrc(config, fn):
LOG.info("Generating a file at [%s] that will contain your environment settings." % (fn))
env_rc.generate_local_rc(fn, config)
contents = env_rc.RcGenerator(config).generate()
with open(fn, "w") as fh:
fh.write(contents)
def _run_components(action_name, component_order, components, distro, root_dir, program_args):