From dacb1fc79ebd7d962991c26bbfd8117c2318ef39 Mon Sep 17 00:00:00 2001 From: Qian Deng Date: Thu, 1 Aug 2019 08:02:08 +0000 Subject: [PATCH] Add healthcheck in Dockerfile* redis* jobservice Signed-off-by: Qian Deng --- Makefile | 7 +++---- make/photon/db/Dockerfile | 8 ++++---- make/photon/db/docker-entrypoint.sh | 1 - make/photon/jobservice/Dockerfile | 2 ++ make/photon/portal/Dockerfile | 9 +++------ make/photon/prepare/utils/clair.py | 4 ++-- make/photon/prepare/utils/core.py | 4 ++-- make/photon/prepare/utils/db.py | 10 +++------- make/photon/prepare/utils/jobservice.py | 10 ++++------ make/photon/prepare/utils/log.py | 4 ++-- make/photon/prepare/utils/misc.py | 22 +++++++++++++++++++++- make/photon/prepare/utils/nginx.py | 5 ++--- make/photon/prepare/utils/notary.py | 6 +++--- make/photon/prepare/utils/redis.py | 9 ++------- make/photon/prepare/utils/registry.py | 4 ++-- make/photon/prepare/utils/registry_ctl.py | 4 ++-- make/photon/redis/Dockerfile | 7 ++++--- make/photon/redis/docker-entrypoint.sh | 13 ------------- make/photon/redis/docker-healthcheck | 9 +++++++++ make/prepare | 10 +++++----- 20 files changed, 75 insertions(+), 73 deletions(-) delete mode 100644 make/photon/redis/docker-entrypoint.sh create mode 100644 make/photon/redis/docker-healthcheck diff --git a/Makefile b/Makefile index 4bc8a3f0f..9178e4198 100644 --- a/Makefile +++ b/Makefile @@ -242,7 +242,7 @@ PACKAGE_ONLINE_PARA=-zcvf harbor-online-installer-$(PKGVERSIONTAG).tgz \ $(HARBORPKG)/install.sh \ $(HARBORPKG)/harbor.yml -DOCKERCOMPOSE_LIST=-f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME) +DOCKERCOMPOSE_FILE_OPT=-f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME) ifeq ($(NOTARYFLAG), true) DOCKERSAVE_PARA+= goharbor/notary-server-photon:$(NOTARYVERSION)-$(VERSIONTAG) goharbor/notary-signer-photon:$(NOTARYVERSION)-$(VERSIONTAG) @@ -412,17 +412,16 @@ pushimage: start: @echo "loading harbor images..." - @$(DOCKERCOMPOSECMD) $(DOCKERCOMPOSE_LIST) up -d + @$(DOCKERCOMPOSECMD) $(DOCKERCOMPOSE_FILE_OPT) up -d @echo "Start complete. You can visit harbor now." down: - @echo "Please make sure to set -e NOTARYFLAG=true/CLAIRFLAG=true/CHARTFLAG=true if you are using Notary/CLAIR/Chartmuseum in Harbor, otherwise the Notary/CLAIR/Chartmuseum containers cannot be stopped automatically." @while [ -z "$$CONTINUE" ]; do \ read -r -p "Type anything but Y or y to exit. [Y/N]: " CONTINUE; \ done ; \ [ $$CONTINUE = "y" ] || [ $$CONTINUE = "Y" ] || (echo "Exiting."; exit 1;) @echo "stoping harbor instance..." - @$(DOCKERCOMPOSECMD) $(DOCKERCOMPOSE_LIST) down -v + @$(DOCKERCOMPOSECMD) $(DOCKERCOMPOSE_FILE_OPT) down -v @echo "Done." swagger_client: diff --git a/make/photon/db/Dockerfile b/make/photon/db/Dockerfile index 6701520e5..e9d765393 100644 --- a/make/photon/db/Dockerfile +++ b/make/photon/db/Dockerfile @@ -18,15 +18,15 @@ RUN tdnf erase -y toybox && tdnf install -y util-linux net-tools VOLUME /var/lib/postgresql/data -COPY ./make/photon/db/docker-entrypoint.sh /entrypoint.sh +COPY ./make/photon/db/docker-entrypoint.sh /docker-entrypoint.sh COPY ./make/photon/db/docker-healthcheck.sh /docker-healthcheck.sh COPY ./make/photon/db/initial-notaryserver.sql /docker-entrypoint-initdb.d/ COPY ./make/photon/db/initial-notarysigner.sql /docker-entrypoint-initdb.d/ COPY ./make/photon/db/initial-registry.sql /docker-entrypoint-initdb.d/ -RUN chown -R postgres:postgres /entrypoint.sh /docker-healthcheck.sh /docker-entrypoint-initdb.d \ - && chmod u+x /entrypoint.sh /docker-healthcheck.sh +RUN chown -R postgres:postgres /docker-entrypoint.sh /docker-healthcheck.sh /docker-entrypoint-initdb.d \ + && chmod u+x /docker-entrypoint.sh /docker-healthcheck.sh -ENTRYPOINT ["/entrypoint.sh"] +ENTRYPOINT ["/docker-entrypoint.sh"] HEALTHCHECK CMD ["/docker-healthcheck.sh"] EXPOSE 5432 diff --git a/make/photon/db/docker-entrypoint.sh b/make/photon/db/docker-entrypoint.sh index 606b805ba..abfabe4ec 100644 --- a/make/photon/db/docker-entrypoint.sh +++ b/make/photon/db/docker-entrypoint.sh @@ -23,7 +23,6 @@ file_env() { unset "$fileVar" } -# chown -R postgres:postgres $PGDATA # look specifically for PG_VERSION, as it is expected in the DB dir if [ ! -s "$PGDATA/PG_VERSION" ]; then file_env 'POSTGRES_INITDB_ARGS' diff --git a/make/photon/jobservice/Dockerfile b/make/photon/jobservice/Dockerfile index 4fbf47e7c..eddb8e65b 100644 --- a/make/photon/jobservice/Dockerfile +++ b/make/photon/jobservice/Dockerfile @@ -14,4 +14,6 @@ USER harbor VOLUME ["/var/log/jobs/"] +HEALTHCHECK CMD curl --fail -s http://127.0.0.1:8080/api/v1/stats || exit 1 + ENTRYPOINT ["/harbor/harbor_jobservice", "-c", "/etc/jobservice/config.yml"] diff --git a/make/photon/portal/Dockerfile b/make/photon/portal/Dockerfile index 86da53cc1..f6adb9bf1 100644 --- a/make/photon/portal/Dockerfile +++ b/make/photon/portal/Dockerfile @@ -1,7 +1,5 @@ FROM node:10.15.0 as nodeportal -RUN mkdir -p /portal_src && mkdir -p /build_dir - COPY src/portal /portal_src COPY ./docs/swagger.yaml /portal_src @@ -10,9 +8,8 @@ WORKDIR /build_dir RUN cp -r /portal_src/* /build_dir \ && ls -la \ && apt-get update \ - && apt-get install python-yaml \ - && cat swagger.yaml | python -c 'import sys, yaml, json; y=yaml.load(sys.stdin.read()); print json.dumps(y)' > swagger.json \ - && cat ./package.json \ + && apt-get install -y --no-install-recommends python-yaml=3.12-1 \ + && python -c 'import sys, yaml, json; y=yaml.load(sys.stdin.read()); print json.dumps(y)' < swagger.yaml > swagger.json \ && npm install \ && npm run build_lib \ && npm run link_lib \ @@ -34,7 +31,7 @@ RUN tdnf install -y nginx sudo >> /dev/null \ && chown -R nginx:nginx /etc/nginx \ && tdnf clean all -EXPOSE 80 +EXPOSE 8080 VOLUME /var/cache/nginx /var/log/nginx /run STOPSIGNAL SIGQUIT diff --git a/make/photon/prepare/utils/clair.py b/make/photon/prepare/utils/clair.py index 72db85038..8d8680249 100644 --- a/make/photon/prepare/utils/clair.py +++ b/make/photon/prepare/utils/clair.py @@ -2,12 +2,12 @@ import os, shutil from g import templates_dir, config_dir, DEFAULT_UID, DEFAULT_GID from .jinja import render_jinja -from .misc import prepare_config_dir +from .misc import prepare_dir clair_template_dir = os.path.join(templates_dir, "clair") def prepare_clair(config_dict): - clair_config_dir = prepare_config_dir(config_dir, "clair") + clair_config_dir = prepare_dir(config_dir, "clair") if os.path.exists(os.path.join(clair_config_dir, "postgresql-init.d")): print("Copying offline data file for clair DB") diff --git a/make/photon/prepare/utils/core.py b/make/photon/prepare/utils/core.py index 9f062efb8..5da6fc6fa 100644 --- a/make/photon/prepare/utils/core.py +++ b/make/photon/prepare/utils/core.py @@ -1,7 +1,7 @@ import shutil, os from g import config_dir, templates_dir -from utils.misc import prepare_config_dir, generate_random_string +from utils.misc import prepare_dir, generate_random_string from utils.jinja import render_jinja core_config_dir = os.path.join(config_dir, "core", "certificates") @@ -33,7 +33,7 @@ def prepare_core(config_dict, with_notary, with_clair, with_chartmuseum): copy_core_config(core_conf_template_path, core_conf) def prepare_core_config_dir(): - prepare_config_dir(core_config_dir) + prepare_dir(core_config_dir) def copy_core_config(core_templates_path, core_config_path): shutil.copyfile(core_templates_path, core_config_path) diff --git a/make/photon/prepare/utils/db.py b/make/photon/prepare/utils/db.py index 2721e10bd..30b7e050d 100644 --- a/make/photon/prepare/utils/db.py +++ b/make/photon/prepare/utils/db.py @@ -1,7 +1,7 @@ import os from g import config_dir, templates_dir, data_dir, PG_UID, PG_GID -from utils.misc import prepare_config_dir +from utils.misc import prepare_dir from utils.jinja import render_jinja db_config_dir = os.path.join(config_dir, "db") @@ -10,12 +10,8 @@ db_conf_env = os.path.join(config_dir, "db", "env") database_data_path = os.path.join(data_dir, 'database') def prepare_db(config_dict): - prepare_config_dir(database_data_path) - stat_info = os.stat(database_data_path) - uid, gid = stat_info.st_uid, stat_info.st_gid - if not (uid == PG_UID and gid == PG_GID): - os.chown(database_data_path, PG_UID, PG_GID) - prepare_config_dir(db_config_dir) + prepare_dir(database_data_path, uid=PG_UID, gid=PG_GID) + prepare_dir(db_config_dir) render_jinja( db_env_template_path, db_conf_env, diff --git a/make/photon/prepare/utils/jobservice.py b/make/photon/prepare/utils/jobservice.py index 422af3bbe..1b10900ee 100644 --- a/make/photon/prepare/utils/jobservice.py +++ b/make/photon/prepare/utils/jobservice.py @@ -1,7 +1,7 @@ import os from g import config_dir, DEFAULT_GID, DEFAULT_UID, templates_dir -from utils.misc import prepare_config_dir +from utils.misc import prepare_dir from utils.jinja import render_jinja job_config_dir = os.path.join(config_dir, "jobservice") @@ -10,16 +10,14 @@ job_service_conf_env = os.path.join(config_dir, "jobservice", "env") job_service_conf_template_path = os.path.join(templates_dir, "jobservice", "config.yml.jinja") jobservice_conf = os.path.join(config_dir, "jobservice", "config.yml") - def prepare_job_service(config_dict): - prepare_config_dir(job_config_dir) + prepare_dir(job_config_dir, uid=DEFAULT_UID, gid=DEFAULT_GID) log_level = config_dict['log_level'].upper() # Job log is stored in data dir job_log_dir = os.path.join('/data', "job_logs") - file_path = prepare_config_dir(job_log_dir) - os.chown(file_path, DEFAULT_UID, DEFAULT_GID) + prepare_dir(job_log_dir, uid=DEFAULT_UID, gid=DEFAULT_GID) # Render Jobservice env render_jinja( job_service_env_template_path, @@ -34,4 +32,4 @@ def prepare_job_service(config_dict): gid=DEFAULT_GID, max_job_workers=config_dict['max_job_workers'], redis_url=config_dict['redis_url_js'], - level=log_level) \ No newline at end of file + level=log_level) diff --git a/make/photon/prepare/utils/log.py b/make/photon/prepare/utils/log.py index 029c42de8..a8a2a1d20 100644 --- a/make/photon/prepare/utils/log.py +++ b/make/photon/prepare/utils/log.py @@ -1,7 +1,7 @@ import os from g import config_dir, templates_dir, DEFAULT_GID, DEFAULT_UID -from utils.misc import prepare_config_dir +from utils.misc import prepare_dir from utils.jinja import render_jinja log_config_dir = os.path.join(config_dir, "log") @@ -15,7 +15,7 @@ log_syslog_docker_template_path = os.path.join(templates_dir, 'log', 'rsyslog_do log_syslog_docker_config = os.path.join(config_dir, 'log', 'rsyslog_docker.conf') def prepare_log_configs(config_dict): - prepare_config_dir(log_config_dir) + prepare_dir(log_config_dir) # Render Log config render_jinja( diff --git a/make/photon/prepare/utils/misc.py b/make/photon/prepare/utils/misc.py index fe6bcc7f8..e7b62faff 100644 --- a/make/photon/prepare/utils/misc.py +++ b/make/photon/prepare/utils/misc.py @@ -3,7 +3,7 @@ import string import random from g import DEFAULT_UID, DEFAULT_GID - +from pathlib import Path # To meet security requirement # By default it will change file mode to 0600, and make the owner of the file to 10000:10000 @@ -84,6 +84,26 @@ def prepare_config_dir(root, *name): os.makedirs(absolute_path) return absolute_path +def prepare_dir(root: str, *args, **kwargs) -> str: + gid, uid = kwargs.get('gid'), kwargs.get('uid') + absolute_path = Path(os.path.join(root, *args)) + if absolute_path.is_file(): + raise Exception('Path exists and the type is regular file') + mode = kwargs.get('mode') or 0o755 + absolute_path.mkdir(mode, parents=True, exist_ok=True) + + # if uid or gid not None, then change the ownership of this dir + if not(gid is None and uid is None): + dir_uid, dir_gid = absolute_path.stat().st_uid, absolute_path.stat().st_gid + if uid is None: + uid = dir_uid + if gid is None: + gid = dir_gid + os.chown(absolute_path, uid, gid) + + return str(absolute_path) + + def delfile(src): if os.path.isfile(src): diff --git a/make/photon/prepare/utils/nginx.py b/make/photon/prepare/utils/nginx.py index ee40b5f2d..74fc3deab 100644 --- a/make/photon/prepare/utils/nginx.py +++ b/make/photon/prepare/utils/nginx.py @@ -3,7 +3,7 @@ from fnmatch import fnmatch from pathlib import Path from g import config_dir, templates_dir, DEFAULT_GID, DEFAULT_UID -from utils.misc import prepare_config_dir, mark_file +from utils.misc import prepare_dir, mark_file from utils.jinja import render_jinja from utils.cert import SSL_CERT_KEY_PATH, SSL_CERT_PATH @@ -17,8 +17,7 @@ CUSTOM_NGINX_LOCATION_FILE_PATTERN_HTTPS = 'harbor.https.*.conf' CUSTOM_NGINX_LOCATION_FILE_PATTERN_HTTP = 'harbor.http.*.conf' def prepare_nginx(config_dict): - file_path = prepare_config_dir(nginx_confd_dir) - os.chown(file_path, DEFAULT_UID, DEFAULT_GID) + prepare_dir(nginx_confd_dir, uid=DEFAULT_UID, gid=DEFAULT_GID) render_nginx_template(config_dict) def render_nginx_template(config_dict): diff --git a/make/photon/prepare/utils/notary.py b/make/photon/prepare/utils/notary.py index 87dae8d08..2e571a462 100644 --- a/make/photon/prepare/utils/notary.py +++ b/make/photon/prepare/utils/notary.py @@ -2,7 +2,7 @@ import os, shutil, pathlib from g import templates_dir, config_dir, root_crt_path, secret_key_dir,DEFAULT_UID, DEFAULT_GID from .cert import openssl_installed, create_cert, create_root_cert, get_alias from .jinja import render_jinja -from .misc import mark_file, prepare_config_dir +from .misc import mark_file, prepare_dir notary_template_dir = os.path.join(templates_dir, "notary") notary_signer_pg_template = os.path.join(notary_template_dir, "signer-config.postgres.json.jinja") @@ -20,12 +20,12 @@ notary_server_env_path = os.path.join(notary_config_dir, "server_env") def prepare_env_notary(nginx_config_dir): - notary_config_dir = prepare_config_dir(config_dir, "notary") + notary_config_dir = prepare_dir(config_dir, "notary") old_signer_cert_secret_path = pathlib.Path(os.path.join(config_dir, 'notary-signer.crt')) old_signer_key_secret_path = pathlib.Path(os.path.join(config_dir, 'notary-signer.key')) old_signer_ca_cert_secret_path = pathlib.Path(os.path.join(config_dir, 'notary-signer-ca.crt')) - notary_secret_dir = prepare_config_dir('/secret/notary') + notary_secret_dir = prepare_dir('/secret/notary') signer_cert_secret_path = pathlib.Path(os.path.join(notary_secret_dir, 'notary-signer.crt')) signer_key_secret_path = pathlib.Path(os.path.join(notary_secret_dir, 'notary-signer.key')) signer_ca_cert_secret_path = pathlib.Path(os.path.join(notary_secret_dir, 'notary-signer-ca.crt')) diff --git a/make/photon/prepare/utils/redis.py b/make/photon/prepare/utils/redis.py index d8a5b562a..751a2475a 100644 --- a/make/photon/prepare/utils/redis.py +++ b/make/photon/prepare/utils/redis.py @@ -1,14 +1,9 @@ import os from g import data_dir, REDIS_UID, REDIS_GID -from utils.misc import prepare_config_dir +from utils.misc import prepare_dir redis_data_path = os.path.join(data_dir, 'redis') def prepare_redis(config_dict): - prepare_config_dir(redis_data_path) - - stat_info = os.stat(redis_data_path) - uid, gid = stat_info.st_uid, stat_info.st_gid - if not (uid == REDIS_UID and gid == REDIS_GID): - os.chown(redis_data_path, REDIS_UID, REDIS_GID) \ No newline at end of file + prepare_dir(redis_data_path, uid=REDIS_UID, gid=REDIS_GID) diff --git a/make/photon/prepare/utils/registry.py b/make/photon/prepare/utils/registry.py index e07a91bdb..bd42f183d 100644 --- a/make/photon/prepare/utils/registry.py +++ b/make/photon/prepare/utils/registry.py @@ -1,7 +1,7 @@ import os, copy from g import config_dir, templates_dir, DEFAULT_GID, DEFAULT_UID -from utils.misc import prepare_config_dir +from utils.misc import prepare_dir from utils.jinja import render_jinja @@ -11,7 +11,7 @@ registry_conf = os.path.join(config_dir, "registry", "config.yml") def prepare_registry(config_dict): - prepare_config_dir(registry_config_dir) + prepare_dir(registry_config_dir) storage_provider_info = get_storage_provider_info( config_dict['storage_provider_name'], diff --git a/make/photon/prepare/utils/registry_ctl.py b/make/photon/prepare/utils/registry_ctl.py index b3fc936f6..8ffe68104 100644 --- a/make/photon/prepare/utils/registry_ctl.py +++ b/make/photon/prepare/utils/registry_ctl.py @@ -1,7 +1,7 @@ import os, shutil from g import config_dir, templates_dir -from utils.misc import prepare_config_dir +from utils.misc import prepare_dir from utils.jinja import render_jinja registryctl_config_dir = os.path.join(config_dir, "registryctl") @@ -24,7 +24,7 @@ def prepare_registry_ctl(config_dict): copy_registry_ctl_conf(registryctl_config_template_path, registryctl_conf) def prepare_registry_ctl_config_dir(): - prepare_config_dir(registryctl_config_dir) + prepare_dir(registryctl_config_dir) def copy_registry_ctl_conf(src, dst): shutil.copyfile(src, dst) \ No newline at end of file diff --git a/make/photon/redis/Dockerfile b/make/photon/redis/Dockerfile index c866f9505..a90873b4b 100644 --- a/make/photon/redis/Dockerfile +++ b/make/photon/redis/Dockerfile @@ -4,11 +4,12 @@ RUN tdnf install -y redis sudo VOLUME /var/lib/redis WORKDIR /var/lib/redis -COPY ./make/photon/redis/docker-entrypoint.sh /usr/bin/ +COPY ./make/photon/redis/docker-healthcheck /usr/bin/ COPY ./make/photon/redis/redis.conf /etc/redis.conf -RUN chmod +x /usr/bin/docker-entrypoint.sh \ +RUN chmod +x /usr/bin/docker-healthcheck \ && chown redis:redis /etc/redis.conf -USER redis +HEALTHCHECK CMD ["docker-healthcheck"] +USER redis EXPOSE 6379 CMD ["redis-server", "/etc/redis.conf"] diff --git a/make/photon/redis/docker-entrypoint.sh b/make/photon/redis/docker-entrypoint.sh deleted file mode 100644 index 5f19ac33d..000000000 --- a/make/photon/redis/docker-entrypoint.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -set -e - -if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then - set -- redis-server "$@" -fi - -if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then - chown -R redis . - exec sudo -u redis "$@" -fi - -exec "$@" diff --git a/make/photon/redis/docker-healthcheck b/make/photon/redis/docker-healthcheck new file mode 100644 index 000000000..80f5cc480 --- /dev/null +++ b/make/photon/redis/docker-healthcheck @@ -0,0 +1,9 @@ +#!/bin/bash + +set -eo pipefail + +if ping="$(redis-cli -h "127.0.0.1" ping)" && [ "$ping" = 'PONG' ]; then + exit 0 +fi + +exit 1 \ No newline at end of file diff --git a/make/prepare b/make/prepare index cca060f45..28d570c92 100755 --- a/make/prepare +++ b/make/prepare @@ -45,11 +45,11 @@ secret_dir=${data_path}/secret config_dir=$harbor_prepare_path/common/config # Run prepare script -docker run --rm -v $input_dir:/input \ - -v $data_path:/data \ - -v $harbor_prepare_path:/compose_location \ - -v $config_dir:/config \ - -v $secret_dir:/secret \ +docker run --rm -v $input_dir:/input:z \ + -v $data_path:/data:z \ + -v $harbor_prepare_path:/compose_location:z \ + -v $config_dir:/config:z \ + -v $secret_dir:/secret:z \ goharbor/prepare:dev $@ echo "Clean up the input dir"