Merge pull request #8891 from ninjadq/fix_prepare_file_permission

Fix: prepare permission issue
This commit is contained in:
stonezdj(Daojun Zhang) 2019-09-02 18:07:14 +08:00 committed by GitHub
commit 469018ae9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 33 deletions

View File

@ -19,7 +19,7 @@ templates_dir = "/usr/src/app/templates"
config_dir = '/config' config_dir = '/config'
data_dir = '/data' data_dir = '/data'
secret_dir = '/secret' secret_dir = '/secret'
secret_key_dir='/secret/keys' secret_key_dir = '/secret/keys'
old_private_key_pem_path = Path('/config/core/private_key.pem') old_private_key_pem_path = Path('/config/core/private_key.pem')
old_crt_path = Path('/config/registry/root.crt') old_crt_path = Path('/config/registry/root.crt')

View File

@ -4,8 +4,11 @@ from pathlib import Path
from subprocess import DEVNULL from subprocess import DEVNULL
from functools import wraps from functools import wraps
from .misc import mark_file from g import DEFAULT_GID, DEFAULT_UID
from .misc import generate_random_string from .misc import (
mark_file,
generate_random_string,
check_permission)
SSL_CERT_PATH = os.path.join("/etc/cert", "server.crt") SSL_CERT_PATH = os.path.join("/etc/cert", "server.crt")
SSL_CERT_KEY_PATH = os.path.join("/etc/cert", "server.key") SSL_CERT_KEY_PATH = os.path.join("/etc/cert", "server.key")
@ -101,4 +104,10 @@ def prepare_ca(
mark_file(root_crt_path) mark_file(root_crt_path)
else: else:
shutil.move(old_crt_path, root_crt_path) shutil.move(old_crt_path, root_crt_path)
shutil.move(old_private_key_pem_path, private_key_pem_path) shutil.move(old_private_key_pem_path, private_key_pem_path)
if not check_permission(root_crt_path, uid=DEFAULT_UID, gid=DEFAULT_GID):
os.chown(root_crt_path, DEFAULT_UID, DEFAULT_GID)
if not check_permission(private_key_pem_path, uid=DEFAULT_UID, gid=DEFAULT_GID):
os.chown(private_key_pem_path, DEFAULT_UID, DEFAULT_GID)

View File

@ -1,17 +1,19 @@
import os, shutil import os, shutil
from g import templates_dir, config_dir from g import templates_dir, config_dir, data_dir, DEFAULT_UID, DEFAULT_GID
from .jinja import render_jinja from .jinja import render_jinja
from .misc import prepare_dir
chartm_temp_dir = os.path.join(templates_dir, "chartserver") chart_museum_temp_dir = os.path.join(templates_dir, "chartserver")
chartm_env_temp = os.path.join(chartm_temp_dir, "env.jinja") chart_museum_env_temp = os.path.join(chart_museum_temp_dir, "env.jinja")
chartm_config_dir = os.path.join(config_dir, "chartserver") chart_museum_config_dir = os.path.join(config_dir, "chartserver")
chartm_env = os.path.join(config_dir, "chartserver", "env") chart_museum_env = os.path.join(config_dir, "chartserver", "env")
chart_museum_data_dir = os.path.join(data_dir, 'chart_storage')
def prepare_chartmuseum(config_dict): def prepare_chartmuseum(config_dict):
core_secret = config_dict['core_secret']
redis_host = config_dict['redis_host'] redis_host = config_dict['redis_host']
redis_port = config_dict['redis_port'] redis_port = config_dict['redis_port']
redis_password = config_dict['redis_password'] redis_password = config_dict['redis_password']
@ -19,9 +21,8 @@ def prepare_chartmuseum(config_dict):
storage_provider_name = config_dict['storage_provider_name'] storage_provider_name = config_dict['storage_provider_name']
storage_provider_config_map = config_dict['storage_provider_config'] storage_provider_config_map = config_dict['storage_provider_config']
if not os.path.isdir(chartm_config_dir): prepare_dir(chart_museum_data_dir, uid=DEFAULT_UID, gid=DEFAULT_GID)
print ("Create config folder: %s" % chartm_config_dir) prepare_dir(chart_museum_config_dir)
os.makedirs(chartm_config_dir)
# process redis info # process redis info
cache_store = "redis" cache_store = "redis"
@ -94,8 +95,8 @@ def prepare_chartmuseum(config_dict):
all_storage_provider_configs = ('\n').join(storage_provider_config_options) all_storage_provider_configs = ('\n').join(storage_provider_config_options)
render_jinja( render_jinja(
chartm_env_temp, chart_museum_env_temp,
chartm_env, chart_museum_env,
cache_store=cache_store, cache_store=cache_store,
cache_redis_addr=cache_redis_addr, cache_redis_addr=cache_redis_addr,
cache_redis_password=cache_redis_password, cache_redis_password=cache_redis_password,

View File

@ -1,6 +1,6 @@
import shutil, os import shutil, os
from g import config_dir, templates_dir from g import config_dir, templates_dir, data_dir, DEFAULT_GID, DEFAULT_UID
from utils.misc import prepare_dir, generate_random_string from utils.misc import prepare_dir, generate_random_string
from utils.jinja import render_jinja from utils.jinja import render_jinja
@ -10,8 +10,14 @@ core_conf_env = os.path.join(config_dir, "core", "env")
core_conf_template_path = os.path.join(templates_dir, "core", "app.conf.jinja") core_conf_template_path = os.path.join(templates_dir, "core", "app.conf.jinja")
core_conf = os.path.join(config_dir, "core", "app.conf") core_conf = os.path.join(config_dir, "core", "app.conf")
ca_download_dir = os.path.join(data_dir, 'ca_download')
psc_dir = os.path.join(data_dir, 'psc')
def prepare_core(config_dict, with_notary, with_clair, with_chartmuseum): def prepare_core(config_dict, with_notary, with_clair, with_chartmuseum):
prepare_core_config_dir() prepare_dir(psc_dir, uid=DEFAULT_UID, gid=DEFAULT_GID)
prepare_dir(ca_download_dir, uid=DEFAULT_UID, gid=DEFAULT_GID)
prepare_dir(core_config_dir)
# Render Core # Render Core
# set cache for chart repo server # set cache for chart repo server
# default set 'memory' mode, if redis is configured then set to 'redis' # default set 'memory' mode, if redis is configured then set to 'redis'
@ -32,8 +38,6 @@ def prepare_core(config_dict, with_notary, with_clair, with_chartmuseum):
# Copy Core app.conf # Copy Core app.conf
copy_core_config(core_conf_template_path, core_conf) copy_core_config(core_conf_template_path, core_conf)
def prepare_core_config_dir():
prepare_dir(core_config_dir)
def copy_core_config(core_templates_path, core_config_path): def copy_core_config(core_templates_path, core_config_path):
shutil.copyfile(core_templates_path, core_config_path) shutil.copyfile(core_templates_path, core_config_path)

View File

@ -10,7 +10,7 @@ db_conf_env = os.path.join(config_dir, "db", "env")
database_data_path = os.path.join(data_dir, 'database') database_data_path = os.path.join(data_dir, 'database')
def prepare_db(config_dict): def prepare_db(config_dict):
prepare_dir(database_data_path, uid=PG_UID, gid=PG_GID) prepare_dir(database_data_path, uid=PG_UID, gid=PG_GID, mode=0o700)
prepare_dir(db_config_dir) prepare_dir(db_config_dir)
render_jinja( render_jinja(
db_env_template_path, db_env_template_path,

View File

@ -1,9 +1,10 @@
import os import os
import string import string
import random import random
from pathlib import Path
from g import DEFAULT_UID, DEFAULT_GID from g import DEFAULT_UID, DEFAULT_GID
from pathlib import Path
# To meet security requirement # To meet security requirement
# By default it will change file mode to 0600, and make the owner of the file to 10000:10000 # By default it will change file mode to 0600, and make the owner of the file to 10000:10000
@ -78,19 +79,18 @@ def generate_random_string(length):
return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length)) return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))
def prepare_config_dir(root, *name):
absolute_path = os.path.join(root, *name)
if not os.path.exists(absolute_path):
os.makedirs(absolute_path)
return absolute_path
def prepare_dir(root: str, *args, **kwargs) -> str: def prepare_dir(root: str, *args, **kwargs) -> str:
gid, uid = kwargs.get('gid'), kwargs.get('uid') gid, uid = kwargs.get('gid'), kwargs.get('uid')
absolute_path = Path(os.path.join(root, *args)) absolute_path = Path(os.path.join(root, *args))
if absolute_path.is_file(): if absolute_path.is_file():
raise Exception('Path exists and the type is regular file') raise Exception('Path exists and the type is regular file')
mode = kwargs.get('mode') or 0o755 mode = kwargs.get('mode') or 0o755
absolute_path.mkdir(mode, parents=True, exist_ok=True)
# we need make sure this dir has the right permission
if not absolute_path.exists():
absolute_path.mkdir(mode=mode, parents=True)
elif not check_permission(absolute_path, mode=mode):
absolute_path.chmod(mode)
# if uid or gid not None, then change the ownership of this dir # if uid or gid not None, then change the ownership of this dir
if not(gid is None and uid is None): if not(gid is None and uid is None):
@ -99,7 +99,10 @@ def prepare_dir(root: str, *args, **kwargs) -> str:
uid = dir_uid uid = dir_uid
if gid is None: if gid is None:
gid = dir_gid gid = dir_gid
os.chown(absolute_path, uid, gid) # We decide to recursively chown only if the dir is not owned by correct user
# to save time if the dir is extremely large
if not check_permission(absolute_path, uid, gid):
recursive_chown(absolute_path, uid, gid)
return str(absolute_path) return str(absolute_path)
@ -113,6 +116,27 @@ def delfile(src):
except Exception as e: except Exception as e:
print(e) print(e)
elif os.path.isdir(src): elif os.path.isdir(src):
for item in os.listdir(src): for dir_name in os.listdir(src):
itemsrc = os.path.join(src, item) dir_path = os.path.join(src, dir_name)
delfile(itemsrc) delfile(dir_path)
def recursive_chown(path, uid, gid):
os.chown(path, uid, gid)
for root, dirs, files in os.walk(path):
for d in dirs:
os.chown(os.path.join(root, d), uid, gid)
for f in files:
os.chown(os.path.join(root, f), uid, gid)
def check_permission(path: str, uid:int = None, gid:int = None, mode:int = None):
if not isinstance(path, Path):
path = Path(path)
if uid is not None and uid != path.stat().st_uid:
return False
if gid is not None and gid != path.stat().st_gid:
return False
if mode is not None and (path.stat().st_mode - mode) % 0o1000 != 0:
return False
return True

View File

@ -1,6 +1,6 @@
import os, copy import os, copy
from g import config_dir, templates_dir, DEFAULT_GID, DEFAULT_UID from g import config_dir, templates_dir, DEFAULT_GID, DEFAULT_UID, data_dir
from utils.misc import prepare_dir from utils.misc import prepare_dir
from utils.jinja import render_jinja from utils.jinja import render_jinja
@ -8,6 +8,7 @@ from utils.jinja import render_jinja
registry_config_dir = os.path.join(config_dir, "registry") registry_config_dir = os.path.join(config_dir, "registry")
registry_config_template_path = os.path.join(templates_dir, "registry", "config.yml.jinja") registry_config_template_path = os.path.join(templates_dir, "registry", "config.yml.jinja")
registry_conf = os.path.join(config_dir, "registry", "config.yml") registry_conf = os.path.join(config_dir, "registry", "config.yml")
registry_data_dir = os.path.join(data_dir, 'registry')
levels_map = { levels_map = {
'debug': 'debug', 'debug': 'debug',
@ -18,6 +19,7 @@ levels_map = {
} }
def prepare_registry(config_dict): def prepare_registry(config_dict):
prepare_dir(registry_data_dir, uid=DEFAULT_UID, gid=DEFAULT_GID)
prepare_dir(registry_config_dir) prepare_dir(registry_config_dir)
storage_provider_info = get_storage_provider_info( storage_provider_info = get_storage_provider_info(