Added horizon dependencies (openstackx, novaclient) and got those to work and some function name adjustments.

This commit is contained in:
Joshua Harlow 2012-01-19 16:21:27 -08:00
parent 660135bbf3
commit 6a9c911141
15 changed files with 303 additions and 55 deletions

View File

@ -40,7 +40,7 @@ HORIZON_CONFIG = {
'user_home': 'dashboard.views.user_home',
}
OPENSTACK_HOST = "127.0.0.1"
OPENSTACK_HOST = "%OPENSTACK_HOST%"
OPENSTACK_KEYSTONE_URL = "http://%s:5000/v2.0" % OPENSTACK_HOST
# FIXME: this is only needed until keystone fixes its GET /tenants call
# so that it doesn't return everything for admins

View File

@ -8,7 +8,9 @@
"skip_uninstall_errors": true
},
"pycrypto": {
"version": "2.3"
"version": "2.3",
#this seems broke on uninstall so skip errors on uinstall
"skip_uninstall_errors": true
}
},
"rhel-6": {}

View File

@ -0,0 +1,17 @@
# This is a extended json package definition file
# We allow simple comments (lines starting with a hash symbol)
{
"ubuntu-oneiric": {
"python-prettytable": {
"version": "0.5-1ubuntu1",
"allowed": ">=",
"removable": true
},
"python-argparse": {
"version": "1.1-1ubuntu1",
"allowed": ">=",
"removable": false
}
},
"rhel-6": {}
}

View File

@ -0,0 +1,6 @@
# This is a extended json package definition file
# We allow simple comments (lines starting with a hash symbol)
{
"ubuntu-oneiric": {},
"rhel-6": {}
}

View File

@ -130,7 +130,7 @@ class PkgInstallComponent(ComponentBase, InstallComponent):
am_downloaded += 1
return am_downloaded
def _get_param_map(self, _=None):
def _get_param_map(self, config_fn):
return None
def install(self):
@ -147,21 +147,21 @@ class PkgInstallComponent(ComponentBase, InstallComponent):
def pre_install(self):
pkgs = Util.get_pkg_list(self.distro, self.component_name)
if(len(pkgs)):
mp = self._get_param_map()
mp = self._get_param_map(None)
self.packager.pre_install(pkgs, mp)
return self.tracedir
def post_install(self):
pkgs = Util.get_pkg_list(self.distro, self.component_name)
if(len(pkgs)):
mp = self._get_param_map()
mp = self._get_param_map(None)
self.packager.post_install(pkgs, mp)
return self.tracedir
def _get_config_files(self):
return list()
def _config_adjust(self, contents, _):
def _config_adjust(self, contents, config_fn):
return contents
def _get_full_config_name(self, name):
@ -360,10 +360,10 @@ class ProgramRuntime(ComponentBase, RuntimeComponent):
def _get_apps_to_start(self):
return list()
def _get_app_options(self, _):
def _get_app_options(self, app_name):
return list()
def _get_param_map(self, _=None):
def _get_param_map(self, app_name):
return {
'ROOT': self.appdir,
}

View File

@ -67,7 +67,7 @@ class DBInstaller(PkgInstallComponent):
PkgInstallComponent.__init__(self, TYPE, *args, **kargs)
self.runtime = DBRuntime(*args, **kargs)
def _get_param_map(self, fn=None):
def _get_param_map(self, config_fn):
#this dictionary will be used for parameter replacement
#in pre-install and post-install sections
out = dict()
@ -87,7 +87,7 @@ class DBInstaller(PkgInstallComponent):
if(dbactions and dbactions.get('grant_all')):
#update the DB to give user 'USER'@'%' full control of the all databases:
grant_cmd = dbactions.get('grant_all')
params = self._get_param_map()
params = self._get_param_map(None)
cmds = list()
cmds.append({
'cmd': grant_cmd,

View File

@ -155,7 +155,7 @@ class GlanceInstaller(PythonInstallComponent):
#nothing modified so just return the original
return contents
def _get_param_map(self, fn=None):
def _get_param_map(self, config_fn):
#this dict will be used to fill in the configuration
#params with actual values
mp = dict()

View File

@ -25,11 +25,15 @@ from Component import (PythonUninstallComponent,
LOG = Logger.getLogger("install.horizon")
TYPE = Util.HORIZON
ROOT_HORIZON = 'horizon'
HORIZON_NAME = 'horizon'
ROOT_DASH = 'openstack-dashboard'
DASH_NAME = 'dashboard'
HORIZON_PY_CONF = "horizon_settings.py"
CONFIGS = [HORIZON_PY_CONF]
class HorizonUninstaller(PythonUninstallComponent):
def __init__(self, *args, **kargs):
@ -64,6 +68,17 @@ class HorizonInstaller(PythonInstallComponent):
})
return py_dirs
def _get_config_files(self):
#these are the config files we will be adjusting
return list(CONFIGS)
def _get_param_map(self, config_fn):
#this dict will be used to fill in the configuration
#params with actual values
mp = dict()
mp['OPENSTACK_HOST'] = Util.get_host_ip(self.cfg)
return mp
class HorizonRuntime(NullRuntime):
def __init__(self, *args, **kargs):

View File

@ -85,7 +85,7 @@ class KeystoneInstaller(PythonInstallComponent):
Db.create_db(self.cfg, DB_NAME)
def _setup_data(self):
params = self._get_param_map()
params = self._get_param_map(None)
cmds = _keystone_setup_cmds(self.all_components)
execute_template(*cmds, params=params, ignore_missing=True)
@ -115,7 +115,7 @@ class KeystoneInstaller(PythonInstallComponent):
#nothing modified so just return the original
return contents
def _get_param_map(self, fn=None):
def _get_param_map(self, config_fn):
#these be used to fill in the configuration/cmds +
#params with actual values
mp = dict()

View File

@ -67,7 +67,7 @@ class NovaInstaller(InstallComponent):
lines = nc.generate()
return os.linesep.join(lines)
def _get_param_map(self, fn=None):
def _get_param_map(self, config_fn):
# Not used. NovaConf will be used to generate the config file
mp = dict()
return mp

59
devstack/NovaClient.py Normal file
View File

@ -0,0 +1,59 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# 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 Logger
import Util
#TODO fix these
from Component import (PythonUninstallComponent,
PythonInstallComponent,
NullRuntime)
LOG = Logger.getLogger("install.nova.client")
TYPE = Util.NOVA_CLIENT
class NovaClientUninstaller(PythonUninstallComponent):
def __init__(self, *args, **kargs):
PythonUninstallComponent.__init__(self, TYPE, *args, **kargs)
class NovaClientInstaller(PythonInstallComponent):
def __init__(self, *args, **kargs):
PythonInstallComponent.__init__(self, TYPE, *args, **kargs)
self.git_loc = self.cfg.get("git", "novaclient_repo")
self.git_branch = self.cfg.get("git", "novaclient_branch")
def _get_download_locations(self):
places = PythonInstallComponent._get_download_locations(self)
places.append({
'uri': self.git_loc,
'branch': self.git_branch,
})
return places
def _get_param_map(self, config_fn):
#this dict will be used to fill in the configuration
#params with actual values
mp = dict()
mp['DEST'] = self.appdir
mp['OPENSTACK_HOST'] = Util.get_host_ip(self.cfg)
return mp
class NovaClientRuntime(NullRuntime):
def __init__(self, *args, **kargs):
NullRuntime.__init__(self, TYPE, *args, **kargs)

52
devstack/OpenstackX.py Normal file
View File

@ -0,0 +1,52 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# 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 Logger
import Util
#TODO fix these
from Component import (PythonUninstallComponent,
PythonInstallComponent,
NullRuntime)
LOG = Logger.getLogger("install.openstackx")
TYPE = Util.OPENSTACK_X
class OpenstackXUninstaller(PythonUninstallComponent):
def __init__(self, *args, **kargs):
PythonUninstallComponent.__init__(self, TYPE, *args, **kargs)
class OpenstackXInstaller(PythonInstallComponent):
def __init__(self, *args, **kargs):
PythonInstallComponent.__init__(self, TYPE, *args, **kargs)
self.git_loc = self.cfg.get("git", "openstackx_repo")
self.git_branch = self.cfg.get("git", "openstackx_branch")
def _get_download_locations(self):
places = PythonInstallComponent._get_download_locations(self)
places.append({
'uri': self.git_loc,
'branch': self.git_branch,
})
return places
class OpenstackXRuntime(NullRuntime):
def __init__(self, *args, **kargs):
NullRuntime.__init__(self, TYPE, *args, **kargs)

View File

@ -20,9 +20,11 @@ import Util
def parse():
versionstr = "%prog v" + Util.VERSION_STR
parser = OptionParser(version=versionstr)
#version
version_str = "%prog v" + Util.VERSION_STR
parser = OptionParser(version=version_str)
#non-boolean options
known_actions = sorted(Util.ACTIONS)
actions = "(" + ", ".join(known_actions) + ")"
parser.add_option("-a", "--action",
@ -47,19 +49,35 @@ def parse():
dest="component",
help="stack component, ie %s" % (components))
#boolean options
parser.add_option("-f", "--force",
action="store_true",
dest="force",
help="force ACTION even if no trace found (ACTION dependent)",
default=False)
parser.add_option("-i", "--ignoredeps",
action="store_true",
dest="ignore_deps",
help="ignore dependencies when performing ACTION",
default=False)
parser.add_option("-l", "--listdeps",
action="store_true",
dest="list_deps",
help="just show dependencies of COMPONENT",
default=False)
(options, args) = parser.parse_args()
#extract only what we care about
output = dict()
output['component'] = options.component
output['components'] = options.component
output['dir'] = options.dir
output['action'] = options.action
output['extras'] = args
output['list_deps'] = options.list_deps
output['force'] = options.force
output['ignore_deps'] = options.ignore_deps
output['extras'] = args
return output

View File

@ -53,6 +53,7 @@ PARAM_SUB_REGEX = re.compile(r"%([\w\d]+?)%")
#component name mappings
NOVA = "nova"
NOVA_CLIENT = 'nova-client'
GLANCE = "glance"
QUANTUM = "quantum"
SWIFT = "swift"
@ -61,21 +62,27 @@ KEYSTONE = "keystone"
KEYSTONE_CLIENT = 'keystone-client'
DB = "db"
RABBIT = "rabbit"
COMPONENT_NAMES = [NOVA, GLANCE, QUANTUM,
SWIFT, HORIZON, KEYSTONE,
DB, RABBIT, KEYSTONE_CLIENT]
OPENSTACK_X = 'openstack-x'
COMPONENT_NAMES = [NOVA, NOVA_CLIENT,
GLANCE, QUANTUM,
SWIFT, HORIZON,
KEYSTONE, KEYSTONE_CLIENT,
OPENSTACK_X,
DB, RABBIT]
#ordering of install (lower priority means earlier)
NAMES_PRIORITY = {
DB: 1,
RABBIT: 1,
KEYSTONE: 2,
GLANCE: 3,
QUANTUM: 3,
NOVA: 3,
SWIFT: 3,
HORIZON: 3,
KEYSTONE_CLIENT: 4,
RABBIT: 2,
KEYSTONE: 3,
GLANCE: 4,
QUANTUM: 4,
SWIFT: 4,
NOVA: 5,
KEYSTONE_CLIENT: 6,
NOVA_CLIENT: 6,
OPENSTACK_X: 6,
HORIZON: 10,
}
#when a component is asked for it may
@ -89,7 +96,7 @@ COMPONENT_DEPENDENCIES = {
KEYSTONE: [DB],
NOVA: [KEYSTONE, GLANCE, DB, RABBIT],
SWIFT: [],
HORIZON: [KEYSTONE_CLIENT, GLANCE],
HORIZON: [KEYSTONE_CLIENT, GLANCE, NOVA_CLIENT, OPENSTACK_X],
QUANTUM: [],
}
@ -163,6 +170,11 @@ PKG_MAP = {
Shell.joinpths(STACK_CONFIG_DIR, "pkgs", "nova.json"),
Shell.joinpths(STACK_CONFIG_DIR, "pkgs", "general.json"),
],
NOVA_CLIENT:
[
Shell.joinpths(STACK_CONFIG_DIR, "pkgs", "nova-client.json"),
Shell.joinpths(STACK_CONFIG_DIR, "pkgs", "general.json"),
],
GLANCE:
[
Shell.joinpths(STACK_CONFIG_DIR, "pkgs", "general.json"),
@ -195,6 +207,10 @@ PKG_MAP = {
[
Shell.joinpths(STACK_CONFIG_DIR, "pkgs", 'rabbitmq.json'),
],
OPENSTACK_X:
[
Shell.joinpths(STACK_CONFIG_DIR, "pkgs", 'openstackx.json'),
],
}
LOG = Logger.getLogger("install.util")

113
stack
View File

@ -26,9 +26,11 @@ import Options
#TODO fix these
from Util import (welcome, rcf8222date, determine_os,
prioritize_components, resolve_dependencies)
from Util import (NOVA, GLANCE, QUANTUM, SWIFT, KEYSTONE, HORIZON, DB, RABBIT, KEYSTONE_CLIENT,
INSTALL, UNINSTALL, START, STOP,
ACTIONS, COMPONENT_NAMES, NAMES_PRIORITY,
from Util import (NOVA, GLANCE, QUANTUM, SWIFT, KEYSTONE,
HORIZON, DB, RABBIT, KEYSTONE_CLIENT,
NOVA_CLIENT, OPENSTACK_X)
from Util import(INSTALL, UNINSTALL, START, STOP,
ACTIONS, COMPONENT_NAMES, NAMES_PRIORITY, COMPONENT_DEPENDENCIES,
UBUNTU11, RHEL6,
STACK_CFG_LOC, DEVSTACK)
from Shell import (mkdir, joinpths, unlink)
@ -45,6 +47,8 @@ import Db
import Rabbit
import Config
import KeystoneClient
import NovaClient
import OpenstackX
LOG = Logger.getLogger("install")
@ -60,6 +64,8 @@ ACTION_CLASSES = {
DB: Db.DBInstaller,
RABBIT: Rabbit.RabbitInstaller,
KEYSTONE_CLIENT: KeystoneClient.KeyStoneClientInstaller,
NOVA_CLIENT: NovaClient.NovaClientInstaller,
OPENSTACK_X: OpenstackX.OpenstackXInstaller,
},
UNINSTALL: {
NOVA: Nova.NovaUninstaller,
@ -71,6 +77,8 @@ ACTION_CLASSES = {
DB: Db.DBUninstaller,
RABBIT: Rabbit.RabbitUninstaller,
KEYSTONE_CLIENT: KeystoneClient.KeyStoneClientUninstaller,
NOVA_CLIENT: NovaClient.NovaClientUninstaller,
OPENSTACK_X: OpenstackX.OpenstackXUninstaller,
},
START: {
NOVA: Nova.NovaRuntime,
@ -82,6 +90,8 @@ ACTION_CLASSES = {
DB: Db.DBRuntime,
RABBIT: Rabbit.RabbitRuntime,
KEYSTONE_CLIENT: KeystoneClient.KeyStoneClientRuntime,
NOVA_CLIENT: NovaClient.NovaClientRuntime,
OPENSTACK_X: OpenstackX.OpenstackXRuntime,
},
STOP: {
NOVA: Nova.NovaRuntime,
@ -93,6 +103,8 @@ ACTION_CLASSES = {
DB: Db.DBRuntime,
RABBIT: Rabbit.RabbitRuntime,
KEYSTONE_CLIENT: KeystoneClient.KeyStoneClientRuntime,
NOVA_CLIENT: NovaClient.NovaClientRuntime,
OPENSTACK_X: OpenstackX.OpenstackXRuntime,
},
}
@ -259,49 +271,80 @@ def check_python():
return True
def main():
if(not check_python()):
LOG.error("Your python version is to old, please upgrade to >= 2.6!")
return 1
me = __file__
args = Options.parse()
components = args.pop("component") or []
def run_list_only(prog, args):
components = args.pop("components") or []
#clean the names up and see what is valid after an intersection
components = set([x.lower().strip() for x in components])
components = set(COMPONENT_NAMES).intersection(components)
if(len(components) == 0):
#assume user wants them all
components = list(COMPONENT_NAMES)
components = sorted(components)
components.reverse()
shown = set()
left_show = list(components)
while(len(left_show) != 0):
c = left_show.pop()
deps = COMPONENT_DEPENDENCIES.get(c) or []
cname = ""
if(len(deps) >= 1):
cname = "component"
if(cname > 1):
cname += "s"
cname += ":"
if(len(deps) == 0):
cname = "no components."
LOG.info("%s depends on %s" % (c, cname))
if(len(deps)):
for d in deps:
LOG.info("\t%s" % (d))
shown.add(c)
for d in deps:
if(d not in shown and d not in left_show):
left_show.append(d)
return True
def run_action(prog, args):
components = args.pop("components") or []
if(len(components) == 0):
LOG.error("No components specified!")
LOG.info("Perhaps you should try %s --help" % (prog))
return False
else:
#clean the names up and see what is valid after an intersection
components = set([x.lower().strip() for x in components])
components = set(COMPONENT_NAMES).intersection(components)
if(len(components) == 0):
LOG.error("No valid components specified!")
LOG.info("Perhaps you should try %s --help" % (me))
return 1
LOG.info("Perhaps you should try %s --help" % (prog))
return False
#extract + normalize the action
ignore_deps = args.pop('ignore_deps', False)
action = args.pop("action") or ""
#normalize the action
action = action.strip().lower()
if(not (action in ACTIONS)):
LOG.error("No valid action specified!")
LOG.info("Perhaps you should try %s --help" % (me))
return 1
LOG.info("Perhaps you should try %s --help" % (prog))
return False
rootdir = args.pop("dir") or ""
if(len(rootdir) == 0 or not check_root(action, rootdir)):
LOG.error("No valid root directory specified!")
LOG.info("Perhaps you should try %s --help" % (me))
return 1
LOG.info("Perhaps you should try %s --help" % (prog))
return False
#ensure os/distro is known
(install_os, plt) = determine_os()
if(install_os == None):
LOG.error("Unsupported operating system/distro: %s" % (plt))
return 1
return False
#start it
welcome(action)
#need to figure out dependencies for components (if any)
new_components = resolve_dependencies(action, components)
component_diff = new_components.difference(components)
if(len(component_diff)):
LOG.info("Having to install dependent components: [%s]" % (",".join(component_diff)))
components = new_components
if(not ignore_deps):
new_components = resolve_dependencies(action, components)
component_diff = new_components.difference(components)
if(len(component_diff)):
LOG.info("Having to install dependent components: [%s]" % (", ".join(component_diff)))
components = new_components
#get the right component order (by priority)
components = prioritize_components(components)
#now do it!
@ -311,7 +354,27 @@ def main():
if(resultList and len(resultList)):
msg = "Check [%s] for traces of what happened." % (", ".join(resultList))
LOG.info(msg)
return 0
return True
def main():
if(not check_python()):
LOG.error("Your python version is to old, please upgrade to >= 2.6!")
return 1
#parse and get it done!
args = Options.parse()
me = os.path.basename(sys.argv[0])
#figure out what to do
only_list_deps = args.pop('list_deps', False)
rc_ok = False
if(only_list_deps):
rc_ok = run_list_only(me, args)
else:
rc_ok = run_action(me, args)
if(rc_ok):
return 0
else:
return 1
if __name__ == "__main__":