From: Milan Broz Date: Thu, 2 Jul 2015 13:03:31 +0000 (+0200) Subject: Set owner of directory and keyrings according to owner of /var/lib/ceph. X-Git-Tag: v1.5.26~6^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F314%2Fhead;p=ceph-deploy.git Set owner of directory and keyrings according to owner of /var/lib/ceph. If Ceph is running under a separate ceph user, it requires access to various files under this user. This patch tries to set owner of these files to the current owner of base_dir (/var/lib/ceph). If the ceph directory is owned by root, it expects old installation and should work with old tools as well (avoids --setuser option). Signed-off-by: Milan Broz --- diff --git a/ceph_deploy/hosts/common.py b/ceph_deploy/hosts/common.py index b71db9d..593fbae 100644 --- a/ceph_deploy/hosts/common.py +++ b/ceph_deploy/hosts/common.py @@ -2,6 +2,7 @@ from ceph_deploy.util import paths from ceph_deploy import conf from ceph_deploy.lib import remoto from StringIO import StringIO +from ceph_deploy.util import constants def ceph_version(conn): @@ -15,6 +16,8 @@ def mon_create(distro, args, monitor_keyring, hostname): logger = distro.conn.logger logger.debug('remote hostname: %s' % hostname) path = paths.mon.path(args.cluster, hostname) + uid = distro.conn.remote_module.path_getuid(constants.base_path) + gid = distro.conn.remote_module.path_getgid(constants.base_path) done_path = paths.mon.done(args.cluster, hostname) init_path = paths.mon.init(args.cluster, hostname, distro.init) @@ -30,7 +33,7 @@ def mon_create(distro, args, monitor_keyring, hostname): ) # if the mon path does not exist, create it - distro.conn.remote_module.create_mon_path(path) + distro.conn.remote_module.create_mon_path(path, uid, gid) logger.debug('checking for done path: %s' % done_path) if not distro.conn.remote_module.path_exists(done_path): @@ -44,8 +47,14 @@ def mon_create(distro, args, monitor_keyring, hostname): distro.conn.remote_module.write_monitor_keyring( keyring, monitor_keyring, + uid, gid, ) + user_args = [] + if uid != 0: + user_args = user_args + [ '--setuser', str(uid) ] + if gid != 0: + user_args = user_args + [ '--setgroup', str(gid) ] remoto.process.run( distro.conn, [ @@ -54,23 +63,25 @@ def mon_create(distro, args, monitor_keyring, hostname): '--mkfs', '-i', hostname, '--keyring', keyring, - ], + ] + user_args ) logger.info('unlinking keyring file %s' % keyring) distro.conn.remote_module.unlink(keyring) # create the done file - distro.conn.remote_module.create_done_path(done_path) + distro.conn.remote_module.create_done_path(done_path, uid, gid) # create init path - distro.conn.remote_module.create_init_path(init_path) + distro.conn.remote_module.create_init_path(init_path, uid, gid) def mon_add(distro, args, monitor_keyring): hostname = distro.conn.remote_module.shortname() logger = distro.conn.logger path = paths.mon.path(args.cluster, hostname) + uid = distro.conn.remote_module.path_getuid(constants.base_path) + gid = distro.conn.remote_module.path_getgid(constants.base_path) monmap_path = paths.mon.monmap(args.cluster, hostname) done_path = paths.mon.done(args.cluster, hostname) init_path = paths.mon.init(args.cluster, hostname, distro.init) @@ -87,7 +98,7 @@ def mon_add(distro, args, monitor_keyring): ) # if the mon path does not exist, create it - distro.conn.remote_module.create_mon_path(path) + distro.conn.remote_module.create_mon_path(path, uid, gid) logger.debug('checking for done path: %s' % done_path) if not distro.conn.remote_module.path_exists(done_path): @@ -101,6 +112,7 @@ def mon_add(distro, args, monitor_keyring): distro.conn.remote_module.write_monitor_keyring( keyring, monitor_keyring, + uid, gid, ) # get the monmap @@ -116,6 +128,11 @@ def mon_add(distro, args, monitor_keyring): ) # now use it to prepare the monitor's data dir + user_args = [] + if uid != 0: + user_args = user_args + [ '--setuser', str(uid) ] + if gid != 0: + user_args = user_args + [ '--setgroup', str(gid) ] remoto.process.run( distro.conn, [ @@ -126,7 +143,7 @@ def mon_add(distro, args, monitor_keyring): '--monmap', monmap_path, '--keyring', keyring, - ], + ] + user_args ) # add it @@ -145,10 +162,10 @@ def mon_add(distro, args, monitor_keyring): distro.conn.remote_module.unlink(keyring) # create the done file - distro.conn.remote_module.create_done_path(done_path) + distro.conn.remote_module.create_done_path(done_path, uid, gid) # create init path - distro.conn.remote_module.create_init_path(init_path) + distro.conn.remote_module.create_init_path(init_path, uid, gid) # start the mon using the address remoto.process.run( diff --git a/ceph_deploy/hosts/remotes.py b/ceph_deploy/hosts/remotes.py index ba3e7d8..b6cca93 100644 --- a/ceph_deploy/hosts/remotes.py +++ b/ceph_deploy/hosts/remotes.py @@ -123,7 +123,7 @@ def write_conf(cluster, conf, overwrite): raise RuntimeError(err_msg) -def write_keyring(path, key): +def write_keyring(path, key, uid=-1, gid=-1): """ create a keyring file """ # Note that we *require* to avoid deletion of the temp file # otherwise we risk not being able to copy the contents from @@ -133,27 +133,30 @@ def write_keyring(path, key): tmp_file.close() keyring_dir = os.path.dirname(path) if not path_exists(keyring_dir): - makedir(keyring_dir) + makedir(keyring_dir, uid, gid) shutil.move(tmp_file.name, path) -def create_mon_path(path): +def create_mon_path(path, uid=-1, gid=-1): """create the mon path if it does not exist""" if not os.path.exists(path): os.makedirs(path) + os.chown(path, uid, gid); -def create_done_path(done_path): +def create_done_path(done_path, uid=-1, gid=-1): """create a done file to avoid re-doing the mon deployment""" with file(done_path, 'w'): pass + os.chown(done_path, uid, gid); -def create_init_path(init_path): +def create_init_path(init_path, uid=-1, gid=-1): """create the init path if it does not exist""" if not os.path.exists(init_path): with file(init_path, 'w'): pass + os.chown(init_path, uid, gid); def append_to_file(file_path, contents): @@ -161,6 +164,11 @@ def append_to_file(file_path, contents): with open(file_path, 'a') as f: f.write(contents) +def path_getuid(path): + return os.stat(path).st_uid + +def path_getgid(path): + return os.stat(path).st_gid def readline(path): with open(path) as _file: @@ -179,7 +187,7 @@ def listdir(path): return os.listdir(path) -def makedir(path, ignored=None): +def makedir(path, ignored=None, uid=-1, gid=-1): ignored = ignored or [] try: os.makedirs(path) @@ -189,24 +197,27 @@ def makedir(path, ignored=None): else: # re-raise the original exception raise + else: + os.chown(path, uid, gid); def unlink(_file): os.unlink(_file) -def write_monitor_keyring(keyring, monitor_keyring): +def write_monitor_keyring(keyring, monitor_keyring, uid=-1, gid=-1): """create the monitor keyring file""" - write_file(keyring, monitor_keyring) + write_file(keyring, monitor_keyring, 0600, None, uid, gid) -def write_file(path, content, mode=0644, directory=None): +def write_file(path, content, mode=0644, directory=None, uid=-1, gid=-1): if directory: if path.startswith("/"): path = path[1:] path = os.path.join(directory, path) with os.fdopen(os.open(path, os.O_WRONLY | os.O_CREAT, mode), 'w') as f: f.write(content) + os.chown(path, uid, gid) def touch_file(path): @@ -289,7 +300,7 @@ def make_mon_removed_dir(path, file_name): shutil.move(path, os.path.join('/var/lib/ceph/mon-removed/', file_name)) -def safe_mkdir(path): +def safe_mkdir(path, uid=-1, gid=-1): """ create path if it doesn't exist """ try: os.mkdir(path) @@ -298,9 +309,10 @@ def safe_mkdir(path): pass else: raise + else: + os.chown(path, uid, gid) - -def safe_makedirs(path): +def safe_makedirs(path, uid=-1, gid=-1): """ create path recursively if it doesn't exist """ try: os.makedirs(path) @@ -309,6 +321,8 @@ def safe_makedirs(path): pass else: raise + else: + os.chown(path, uid, gid) def zeroing(dev): diff --git a/ceph_deploy/tests/test_cli_admin.py b/ceph_deploy/tests/test_cli_admin.py index aeb0778..57bfe31 100644 --- a/ceph_deploy/tests/test_cli_admin.py +++ b/ceph_deploy/tests/test_cli_admin.py @@ -44,7 +44,7 @@ def test_write_keyring(tmpdir): distro = MagicMock() distro.conn = MagicMock() - remotes.write_file.func_defaults = (str(tmpdir),) + remotes.write_file.func_defaults = (0644, str(tmpdir), -1, -1) distro.conn.remote_module = remotes distro.conn.remote_module.write_conf = Mock()