Getting the user and group stuff working for horizon.
This commit is contained in:
parent
1a48517931
commit
b70908db4d
@ -1,8 +1,13 @@
|
||||
<VirtualHost *:80>
|
||||
<VirtualHost *:%HORIZON_PORT%>
|
||||
|
||||
#From commit 30439a6dc4
|
||||
#With adjustments to make APACHE_RUN_GROUP a param
|
||||
#and to make HORIZON_PORT a param
|
||||
|
||||
WSGIScriptAlias / %HORIZON_DIR%/openstack-dashboard/dashboard/wsgi/django.wsgi
|
||||
WSGIDaemonProcess horizon user=%USER% group=%USER% processes=3 threads=10
|
||||
WSGIDaemonProcess horizon user=%USER% group=%GROUP% processes=3 threads=10
|
||||
SetEnv APACHE_RUN_USER %USER%
|
||||
SetEnv APACHE_RUN_GROUP %USER%
|
||||
SetEnv APACHE_RUN_GROUP %GROUP%
|
||||
WSGIProcessGroup horizon
|
||||
|
||||
DocumentRoot %HORIZON_DIR%/.blackhole/
|
||||
@ -24,5 +29,6 @@
|
||||
ErrorLog /var/log/apache2/error.log
|
||||
LogLevel warn
|
||||
CustomLog /var/log/apache2/access.log combined
|
||||
|
||||
</VirtualHost>
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Based off of horizon_settings.py from commit 30439a6dc4
|
||||
# With a change to allow OPENSTACK_HOST to come in from
|
||||
# the new script instead of being fixed.
|
||||
# the new script instead of being fixed. Also
|
||||
# QUANTUM_ENABLED was made a param.
|
||||
|
||||
import os
|
||||
|
||||
@ -54,7 +55,7 @@ OPENSTACK_KEYSTONE_DEFAULT_ROLE = "Member"
|
||||
SWIFT_PAGINATE_LIMIT = 100
|
||||
|
||||
# Configure quantum connection details for networking
|
||||
QUANTUM_ENABLED = False
|
||||
QUANTUM_ENABLED = %QUANTUM_ENABLED%
|
||||
QUANTUM_URL = '%s' % OPENSTACK_HOST
|
||||
QUANTUM_PORT = '9696'
|
||||
QUANTUM_TENANT = '1234'
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
# From commit 30439a6dc4
|
||||
|
||||
# Order actually matters in this file so be careful!
|
||||
|
||||
# This was added (so that it dies on errors)
|
||||
set -o errexit
|
||||
|
||||
|
@ -218,14 +218,29 @@ quantum_branch = master
|
||||
|
||||
[quantum]
|
||||
|
||||
# Where your quantum host is at
|
||||
q_host = ${Q_HOST:-$(host:ip)}
|
||||
|
||||
# Which port your quantum host is at
|
||||
q_port = ${Q_PORT:-9696}
|
||||
|
||||
# Which type of quantum plugin you will be using
|
||||
q_plugin = ${Q_PLUGIN:-openvswitch}
|
||||
|
||||
[horizon]
|
||||
|
||||
# What user will apache be serving from
|
||||
apache_user = ${APACHE_USER:-root}
|
||||
#
|
||||
# Root will typically not work (so this is here to fail)
|
||||
# sudo adduser <username> admin will be what you want to set this up.
|
||||
# I typically use "sudo adduser horizon admin"
|
||||
apache_user = ${APACHE_USER:-horizon}
|
||||
|
||||
# This is the group of the previous user (adjust as needed)
|
||||
apache_group = ${APACHE_GROUP:-horizon}
|
||||
|
||||
# Port horizon should run on
|
||||
port = ${HORIZON_PORT:-80}
|
||||
|
||||
[ci]
|
||||
|
||||
|
@ -53,6 +53,8 @@ DB_ACTIONS = {
|
||||
#used as a generic error message
|
||||
BASE_ERROR = 'Currently we do not know how to %s for database type [%s]'
|
||||
|
||||
#used to make params for booting when started (not always take advantage of...)
|
||||
BOOLEAN_OUTPUT = {True: 'true', False: 'false'}
|
||||
|
||||
class DBUninstaller(comp.PkgUninstallComponent):
|
||||
def __init__(self, *args, **kargs):
|
||||
@ -69,7 +71,7 @@ class DBInstaller(comp.PkgInstallComponent):
|
||||
#in pre-install and post-install sections
|
||||
out = dict()
|
||||
out['PASSWORD'] = self.cfg.get("passwords", "sql")
|
||||
out['BOOT_START'] = str(True).lower()
|
||||
out['BOOT_START'] = "%s" % BOOLEAN_OUTPUT.get(True)
|
||||
out['USER'] = self.cfg.get("db", "sql_user")
|
||||
host_ip = self.cfg.get('host', 'ip')
|
||||
out['SERVICE_HOST'] = host_ip
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
from devstack import component as comp
|
||||
from devstack import log as logging
|
||||
@ -38,6 +39,12 @@ BLACKHOLE_DIR = '.blackhole'
|
||||
|
||||
#hopefully this will be distro independent ??
|
||||
APACHE_RESTART_CMD = ['service', 'apache2', 'restart']
|
||||
APACHE_START_CMD = ['service', 'apache2', 'start']
|
||||
APACHE_STOP_CMD = ['service', 'apache2', 'stop']
|
||||
APACHE_STATUS_CMD = ['service', 'apache2', 'status']
|
||||
|
||||
#users which apache may not like starting as
|
||||
BAD_APACHE_USERS = ['root']
|
||||
|
||||
LOG = logging.getLogger("devstack.components.horizon")
|
||||
|
||||
@ -92,6 +99,7 @@ class HorizonInstaller(comp.PythonInstallComponent):
|
||||
#create an empty directory that apache uses as docroot
|
||||
black_dir = sh.joinpths(self.appdir, BLACKHOLE_DIR)
|
||||
self.tracewriter.make_dir(black_dir)
|
||||
return black_dir
|
||||
|
||||
def _sync_db(self):
|
||||
#Initialize the horizon database (it stores sessions and notices shown to users).
|
||||
@ -111,27 +119,47 @@ class HorizonInstaller(comp.PythonInstallComponent):
|
||||
self.tracewriter.touch_file(sh.joinpths(quantum_dir, '__init__.py'))
|
||||
self.tracewriter.touch_file(sh.joinpths(quantum_dir, 'client.py'))
|
||||
|
||||
def _ensure_db_access(self):
|
||||
# ../openstack-dashboard/local needs to be writeable by the runtime user
|
||||
# since currently its storing the sql-lite databases there (TODO fix that)
|
||||
path = sh.joinpths(self.dash_dir, 'local')
|
||||
if(sh.isdir(path)):
|
||||
(user, group) = self._get_apache_user_group()
|
||||
LOG.info("Changing ownership (recursively) of %s so that it can be used by %s - %s",
|
||||
path, user, group)
|
||||
uid = sh.getuid(user)
|
||||
gid = sh.getgid(group)
|
||||
sh.chown_r(path, uid, gid)
|
||||
|
||||
def post_install(self):
|
||||
parent_result = comp.PythonInstallComponent.post_install(self)
|
||||
self._fake_quantum()
|
||||
self._sync_db()
|
||||
self._setup_blackhole()
|
||||
self._ensure_db_access()
|
||||
return parent_result
|
||||
|
||||
def _get_apache_user(self):
|
||||
#TODO will this be the right user?
|
||||
def _get_apache_user_group(self):
|
||||
user = self.cfg.get('horizon', 'apache_user')
|
||||
if(not user):
|
||||
user = sh.getuser()
|
||||
return user
|
||||
if(user in BAD_APACHE_USERS):
|
||||
LOG.warn("You may want to adjust your configuration, user=%s will typically not work with apache", user)
|
||||
group = self.cfg.get('horizon', 'apache_group')
|
||||
if(not group):
|
||||
group = sh.getgroupname()
|
||||
return (user, group)
|
||||
|
||||
def _get_param_map(self, config_fn):
|
||||
#this dict will be used to fill in the configuration
|
||||
#params with actual values
|
||||
mp = dict()
|
||||
if(config_fn == HORIZON_APACHE_CONF):
|
||||
mp['USER'] = self._get_apache_user()
|
||||
(user, group) = self._get_apache_user_group()
|
||||
mp['USER'] = user
|
||||
mp['GROUP'] = group
|
||||
mp['HORIZON_DIR'] = self.appdir
|
||||
mp['HORIZON_PORT'] = self.cfg.get('horizon', 'port')
|
||||
else:
|
||||
#Enable quantum in dashboard, if requested
|
||||
mp['QUANTUM_ENABLED'] = "%s" % (settings.QUANTUM in self.instances)
|
||||
@ -142,3 +170,39 @@ class HorizonInstaller(comp.PythonInstallComponent):
|
||||
class HorizonRuntime(comp.EmptyRuntime):
|
||||
def __init__(self, *args, **kargs):
|
||||
comp.EmptyRuntime.__init__(self, TYPE, *args, **kargs)
|
||||
|
||||
def start(self):
|
||||
curr_status = self.status()
|
||||
if(curr_status == comp.STATUS_STARTED):
|
||||
#restart it ?
|
||||
return self.restart()
|
||||
else:
|
||||
sh.execute(*APACHE_START_CMD,
|
||||
run_as_root=True)
|
||||
return 1
|
||||
|
||||
def restart(self):
|
||||
curr_status = self.status()
|
||||
if(curr_status == comp.STATUS_STARTED):
|
||||
sh.execute(*APACHE_RESTART_CMD,
|
||||
run_as_root=True)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def stop(self):
|
||||
curr_status = self.status()
|
||||
if(curr_status == comp.STATUS_STARTED):
|
||||
sh.execute(*APACHE_STOP_CMD,
|
||||
run_as_root=True)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def status(self):
|
||||
(sysout, _) = sh.execute(*APACHE_STATUS_CMD,
|
||||
check_exit_code=False)
|
||||
if(sysout.find("is running") != -1):
|
||||
return comp.STATUS_STARTED
|
||||
elif(sysout.find("NOT running") != -1):
|
||||
return comp.STATUS_STOPPED
|
||||
else:
|
||||
return comp.STATUS_UNKNOWN
|
||||
|
@ -14,8 +14,10 @@
|
||||
# under the License.
|
||||
|
||||
import getpass
|
||||
import grp
|
||||
import os
|
||||
import os.path
|
||||
import pwd
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
@ -49,11 +51,14 @@ def execute(*cmd, **kwargs):
|
||||
cmd = ROOT_HELPER + list(cmd)
|
||||
|
||||
cmd = [str(c) for c in cmd]
|
||||
execute_cmd = None
|
||||
str_cmd = " ".join(cmd)
|
||||
if(shell):
|
||||
cmd = " ".join(cmd)
|
||||
LOG.debug('Running shell cmd: [%s]' % (cmd))
|
||||
execute_cmd = str_cmd.strip()
|
||||
LOG.debug('Running shell cmd: [%s]' % (str_cmd))
|
||||
else:
|
||||
LOG.debug('Running cmd: [%s]' % (' '.join(cmd)))
|
||||
execute_cmd = cmd
|
||||
LOG.debug('Running cmd: [%s]' % (' '.join(str_cmd)))
|
||||
|
||||
if(process_input != None):
|
||||
LOG.debug('With stdin: %s' % (process_input))
|
||||
@ -86,7 +91,7 @@ def execute(*cmd, **kwargs):
|
||||
for (k, v) in env_overrides.items():
|
||||
process_env[k] = str(v)
|
||||
|
||||
obj = subprocess.Popen(cmd,
|
||||
obj = subprocess.Popen(execute_cmd,
|
||||
stdin=stdin_fh,
|
||||
stdout=stdout_fh,
|
||||
stderr=stderr_fh,
|
||||
@ -103,20 +108,23 @@ def execute(*cmd, **kwargs):
|
||||
|
||||
if 'stdin_fh' not in kwargs.keys():
|
||||
obj.stdin.close()
|
||||
_returncode = obj.returncode
|
||||
LOG.debug('Cmd result had exit code: %s' % _returncode)
|
||||
|
||||
if((not ignore_exit_code) and (_returncode not in check_exit_code)):
|
||||
rc = obj.returncode
|
||||
LOG.debug('Cmd result had exit code: %s' % rc)
|
||||
|
||||
if((not ignore_exit_code) and (rc not in check_exit_code)):
|
||||
(stdout, stderr) = result
|
||||
ecmd = cmd
|
||||
if(not shell):
|
||||
ecmd = ' '.join(cmd)
|
||||
raise excp.ProcessExecutionError(
|
||||
exit_code=_returncode,
|
||||
exit_code=rc,
|
||||
stdout=stdout,
|
||||
stderr=stderr,
|
||||
cmd=ecmd)
|
||||
cmd=str_cmd)
|
||||
else:
|
||||
#log it anyway
|
||||
if(rc not in check_exit_code):
|
||||
(stdout, stderr) = result
|
||||
LOG.debug("A failure may of just happened when running command \"%s\" [%s] (%s, %s)", str_cmd,
|
||||
rc, stdout.strip(), stderr.strip())
|
||||
return result
|
||||
|
||||
|
||||
@ -153,6 +161,16 @@ def _prompt_password(prompt_=None):
|
||||
return getpass.getpass()
|
||||
|
||||
|
||||
def chown_r(path, uid, gid):
|
||||
if(isdir(path)):
|
||||
for root, dirs, files in os.walk(path):
|
||||
os.chown(root, uid, gid)
|
||||
for d in dirs:
|
||||
os.chown(joinpths(root, d), uid, gid)
|
||||
for f in files:
|
||||
os.chown(joinpths(root, f), uid, gid)
|
||||
|
||||
|
||||
def password(prompt_=None, pw_len=8):
|
||||
rd = ""
|
||||
ask_for_pw = env.get_bool(PASS_ASK_ENV, True)
|
||||
@ -271,6 +289,23 @@ def getuser():
|
||||
return getpass.getuser()
|
||||
|
||||
|
||||
def getuid(username):
|
||||
uinfo = pwd.getpwnam(username)
|
||||
return uinfo.pw_gid
|
||||
|
||||
|
||||
def getgid(groupname):
|
||||
grp_info = grp.getgrnam(groupname)
|
||||
return grp_info.gr_gid
|
||||
|
||||
|
||||
def getgroupname(gid=None):
|
||||
if(gid is None):
|
||||
gid = os.getgid()
|
||||
gid_info = grp.getgrgid(gid)
|
||||
return gid_info.gr_name
|
||||
|
||||
|
||||
def unlink(path, ignore_errors=True):
|
||||
try:
|
||||
LOG.debug("Unlinking (removing) %s" % (path))
|
||||
|
Loading…
x
Reference in New Issue
Block a user