Feat: update prepare to support tls

update makefile
add model for prepare
update jinja template for prepare

Signed-off-by: DQ <dengq@vmware.com>
This commit is contained in:
DQ 2020-02-11 13:47:55 +08:00
parent b4e941e961
commit a4855cca36
24 changed files with 567 additions and 153 deletions

View File

@ -17,6 +17,8 @@ https:
certificate: /your/certificate/path
private_key: /your/private/key/path
# internal_tls:
# Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used
# external_url: https://reg.mydomain.com:8433

View File

@ -12,4 +12,4 @@ click = "*"
pylint = "*"
[requires]
python_version = "3.6"
python_version = "3.7.5"

View File

@ -1,11 +1,11 @@
{
"_meta": {
"hash": {
"sha256": "a3c7e13ece64f4447d0bd3648257ca4117192e5d52ff7cdd4b4c2d3109ae6500"
"sha256": "fc86f400c4b9ebc8d4caf833b1e8d8c8962b7f4920b19632e9e4f4e8738ce7e2"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
"python_version": "3.7.5"
},
"sources": [
{
@ -26,11 +26,11 @@
},
"jinja2": {
"hashes": [
"sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013",
"sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b"
"sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f",
"sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"
],
"index": "pypi",
"version": "==2.10.1"
"version": "==2.10.3"
},
"markupsafe": {
"hashes": [
@ -76,51 +76,43 @@
"develop": {
"astroid": {
"hashes": [
"sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4",
"sha256:b65db1bbaac9f9f4d190199bb8680af6f6f84fd3769a5ea883df8a91fe68b4c4"
"sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a",
"sha256:840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42"
],
"version": "==2.2.5"
"version": "==2.3.3"
},
"isort": {
"hashes": [
"sha256:01cb7e1ca5e6c5b3f235f0385057f70558b70d2f00320208825fa62887292f43",
"sha256:268067462aed7eb2a1e237fcb287852f22077de3fb07964e87e00f829eea2d1a"
"sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1",
"sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"
],
"version": "==4.3.17"
"version": "==4.3.21"
},
"lazy-object-proxy": {
"hashes": [
"sha256:0ce34342b419bd8f018e6666bfef729aec3edf62345a53b537a4dcc115746a33",
"sha256:1b668120716eb7ee21d8a38815e5eb3bb8211117d9a90b0f8e21722c0758cc39",
"sha256:209615b0fe4624d79e50220ce3310ca1a9445fd8e6d3572a896e7f9146bbf019",
"sha256:27bf62cb2b1a2068d443ff7097ee33393f8483b570b475db8ebf7e1cba64f088",
"sha256:27ea6fd1c02dcc78172a82fc37fcc0992a94e4cecf53cb6d73f11749825bd98b",
"sha256:2c1b21b44ac9beb0fc848d3993924147ba45c4ebc24be19825e57aabbe74a99e",
"sha256:2df72ab12046a3496a92476020a1a0abf78b2a7db9ff4dc2036b8dd980203ae6",
"sha256:320ffd3de9699d3892048baee45ebfbbf9388a7d65d832d7e580243ade426d2b",
"sha256:50e3b9a464d5d08cc5227413db0d1c4707b6172e4d4d915c1c70e4de0bbff1f5",
"sha256:5276db7ff62bb7b52f77f1f51ed58850e315154249aceb42e7f4c611f0f847ff",
"sha256:61a6cf00dcb1a7f0c773ed4acc509cb636af2d6337a08f362413c76b2b47a8dd",
"sha256:6ae6c4cb59f199d8827c5a07546b2ab7e85d262acaccaacd49b62f53f7c456f7",
"sha256:7661d401d60d8bf15bb5da39e4dd72f5d764c5aff5a86ef52a042506e3e970ff",
"sha256:7bd527f36a605c914efca5d3d014170b2cb184723e423d26b1fb2fd9108e264d",
"sha256:7cb54db3535c8686ea12e9535eb087d32421184eacc6939ef15ef50f83a5e7e2",
"sha256:7f3a2d740291f7f2c111d86a1c4851b70fb000a6c8883a59660d95ad57b9df35",
"sha256:81304b7d8e9c824d058087dcb89144842c8e0dea6d281c031f59f0acf66963d4",
"sha256:933947e8b4fbe617a51528b09851685138b49d511af0b6c0da2539115d6d4514",
"sha256:94223d7f060301b3a8c09c9b3bc3294b56b2188e7d8179c762a1cda72c979252",
"sha256:ab3ca49afcb47058393b0122428358d2fbe0408cf99f1b58b295cfeb4ed39109",
"sha256:bd6292f565ca46dee4e737ebcc20742e3b5be2b01556dafe169f6c65d088875f",
"sha256:cb924aa3e4a3fb644d0c463cad5bc2572649a6a3f68a7f8e4fbe44aaa6d77e4c",
"sha256:d0fc7a286feac9077ec52a927fc9fe8fe2fabab95426722be4c953c9a8bede92",
"sha256:ddc34786490a6e4ec0a855d401034cbd1242ef186c20d79d2166d6a4bd449577",
"sha256:e34b155e36fa9da7e1b7c738ed7767fc9491a62ec6af70fe9da4a057759edc2d",
"sha256:e5b9e8f6bda48460b7b143c3821b21b452cb3a835e6bbd5dd33aa0c8d3f5137d",
"sha256:e81ebf6c5ee9684be8f2c87563880f93eedd56dd2b6146d8a725b50b7e5adb0f",
"sha256:eb91be369f945f10d3a49f5f9be8b3d0b93a4c2be8f8a5b83b0571b8123e0a7a",
"sha256:f460d1ceb0e4a5dcb2a652db0904224f367c9b3c1470d5a7683c0480e582468b"
"sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d",
"sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449",
"sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08",
"sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a",
"sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50",
"sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd",
"sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239",
"sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb",
"sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea",
"sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e",
"sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156",
"sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142",
"sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442",
"sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62",
"sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db",
"sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531",
"sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383",
"sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a",
"sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357",
"sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4",
"sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"
],
"version": "==1.3.1"
"version": "==1.4.3"
},
"mccabe": {
"hashes": [
@ -131,50 +123,50 @@
},
"pylint": {
"hashes": [
"sha256:5d77031694a5fb97ea95e828c8d10fc770a1df6eb3906067aaed42201a8a6a09",
"sha256:723e3db49555abaf9bf79dc474c6b9e2935ad82230b10c1138a71ea41ac0fff1"
"sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd",
"sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4"
],
"index": "pypi",
"version": "==2.3.1"
"version": "==2.4.4"
},
"six": {
"hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
"sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd",
"sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"
],
"version": "==1.12.0"
"version": "==1.13.0"
},
"typed-ast": {
"hashes": [
"sha256:04894d268ba6eab7e093d43107869ad49e7b5ef40d1a94243ea49b352061b200",
"sha256:16616ece19daddc586e499a3d2f560302c11f122b9c692bc216e821ae32aa0d0",
"sha256:252fdae740964b2d3cdfb3f84dcb4d6247a48a6abe2579e8029ab3be3cdc026c",
"sha256:2af80a373af123d0b9f44941a46df67ef0ff7a60f95872412a145f4500a7fc99",
"sha256:2c88d0a913229a06282b285f42a31e063c3bf9071ff65c5ea4c12acb6977c6a7",
"sha256:2ea99c029ebd4b5a308d915cc7fb95b8e1201d60b065450d5d26deb65d3f2bc1",
"sha256:3d2e3ab175fc097d2a51c7a0d3fda442f35ebcc93bb1d7bd9b95ad893e44c04d",
"sha256:4766dd695548a15ee766927bf883fb90c6ac8321be5a60c141f18628fb7f8da8",
"sha256:56b6978798502ef66625a2e0f80cf923da64e328da8bbe16c1ff928c70c873de",
"sha256:5cddb6f8bce14325b2863f9d5ac5c51e07b71b462361fd815d1d7706d3a9d682",
"sha256:644ee788222d81555af543b70a1098f2025db38eaa99226f3a75a6854924d4db",
"sha256:64cf762049fc4775efe6b27161467e76d0ba145862802a65eefc8879086fc6f8",
"sha256:68c362848d9fb71d3c3e5f43c09974a0ae319144634e7a47db62f0f2a54a7fa7",
"sha256:6c1f3c6f6635e611d58e467bf4371883568f0de9ccc4606f17048142dec14a1f",
"sha256:b213d4a02eec4ddf622f4d2fbc539f062af3788d1f332f028a2e19c42da53f15",
"sha256:bb27d4e7805a7de0e35bd0cb1411bc85f807968b2b0539597a49a23b00a622ae",
"sha256:c9d414512eaa417aadae7758bc118868cd2396b0e6138c1dd4fda96679c079d3",
"sha256:f0937165d1e25477b01081c4763d2d9cdc3b18af69cb259dd4f640c9b900fe5e",
"sha256:fb96a6e2c11059ecf84e6741a319f93f683e440e341d4489c9b161eca251cf2a",
"sha256:fc71d2d6ae56a091a8d94f33ec9d0f2001d1cb1db423d8b4355debfe9ce689b7"
"sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161",
"sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e",
"sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e",
"sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0",
"sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c",
"sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47",
"sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631",
"sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4",
"sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34",
"sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b",
"sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2",
"sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e",
"sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a",
"sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233",
"sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1",
"sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36",
"sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d",
"sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a",
"sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66",
"sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"
],
"markers": "implementation_name == 'cpython'",
"version": "==1.3.4"
"markers": "implementation_name == 'cpython' and python_version < '3.8'",
"version": "==1.4.0"
},
"wrapt": {
"hashes": [
"sha256:4aea003270831cceb8a90ff27c4031da6ead7ec1886023b80ce0dfe0adf61533"
"sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"
],
"version": "==1.11.1"
"version": "==1.11.2"
}
}
}

View File

@ -12,27 +12,33 @@ REDIS_UID = 999
REDIS_GID = 999
## Global variable
host_root_dir = '/hostfs'
templates_dir = "/usr/src/app/templates"
host_root_dir = Path('/hostfs')
base_dir = '/harbor_make'
templates_dir = "/usr/src/app/templates"
config_dir = '/config'
data_dir = '/data'
secret_dir = '/secret'
secret_key_dir = '/secret/keys'
config_dir = Path('/config')
data_dir = Path('/data')
secret_dir = data_dir.joinpath('secret')
secret_key_dir = secret_dir.joinpath('keys')
trust_ca_dir = secret_dir.joinpath('keys', 'trust_ca')
internal_tls_dir = secret_dir.joinpath('tls')
storage_ca_bundle_filename = 'storage_ca_bundle.crt'
old_private_key_pem_path = Path('/config/core/private_key.pem')
old_crt_path = Path('/config/registry/root.crt')
private_key_pem_path = Path('/secret/core/private_key.pem')
root_crt_path = Path('/secret/registry/root.crt')
private_key_pem_path = secret_dir.joinpath('core', 'private_key.pem')
root_crt_path = secret_dir.joinpath('registry', 'root.crt')
config_file_path = '/compose_location/harbor.yml'
input_config_path = '/input/harbor.yml'
versions_file_path = Path('/usr/src/app/versions')
cert_dir = os.path.join(config_dir, "nginx", "cert")
core_cert_dir = os.path.join(config_dir, "core", "certificates")
cert_dir = config_dir.joinpath("nginx", "cert")
core_cert_dir = config_dir.joinpath("core", "certificates")
INTERNAL_NO_PROXY_DN = {
'127.0.0.1',

View File

@ -5,7 +5,7 @@ import logging
import click
from utils.misc import delfile
from utils.configs import validate, parse_yaml_config
from utils.cert import prepare_ca, SSL_CERT_KEY_PATH, SSL_CERT_PATH, get_secret_key
from utils.cert import prepare_registry_ca, SSL_CERT_KEY_PATH, SSL_CERT_PATH, get_secret_key
from utils.db import prepare_db
from utils.jobservice import prepare_job_service
from utils.registry import prepare_registry
@ -20,6 +20,7 @@ from utils.chart import prepare_chartmuseum
from utils.docker_compose import prepare_docker_compose
from utils.nginx import prepare_nginx, nginx_confd_dir
from utils.redis import prepare_redis
from utils.internal_tls import prepare_tls
from g import (config_dir, input_config_path, private_key_pem_path, root_crt_path, secret_key_dir,
old_private_key_pem_path, old_crt_path)
@ -49,15 +50,17 @@ def main(conf, with_notary, with_clair, with_trivy, with_chartmuseum):
prepare_db(config_dict)
prepare_job_service(config_dict)
prepare_redis(config_dict)
prepare_tls(config_dict)
get_secret_key(secret_key_dir)
# If Customized cert enabled
prepare_ca(
prepare_registry_ca(
private_key_pem_path=private_key_pem_path,
root_crt_path=root_crt_path,
old_private_key_pem_path=old_private_key_pem_path,
old_crt_path=old_crt_path)
if with_notary:
prepare_notary(config_dict, nginx_confd_dir, SSL_CERT_PATH, SSL_CERT_KEY_PATH)

View File

@ -0,0 +1,136 @@
import os
import logging
from pathlib import Path
from shutil import copytree, rmtree
from g import internal_tls_dir, DEFAULT_GID, DEFAULT_UID, PG_GID, PG_UID
from utils.misc import check_permission, owner_can_read, other_can_read, get_realpath, owner_can_read
class InternalTLS:
harbor_certs_filename = {
'harbor_internal_ca.crt',
'proxy.crt', 'proxy.key',
'core.crt', 'core.key',
'job_service.crt', 'job_service.key',
'registryctl.crt', 'registryctl.key',
'registry.crt', 'registry.key'
}
clair_certs_filename = {
'clair_adapter.crt', 'clair_adapter.key',
'clair.crt', 'clair.key'
}
notary_certs_filename = {
'notary_signer.crt', 'notary_signer.key',
'notary_server.crt', 'notary_server.key'
}
chart_museum_filename = {
'chartmuseum.crt',
'chartmuseum.key'
}
db_certs_filename = {
'harbor_db.crt', 'harbor_db.key'
}
def __init__(self, tls_dir: str, data_volume:str, **kwargs):
self.data_volume = data_volume
if not tls_dir:
self.enabled = False
else:
self.enabled = True
self.tls_dir = tls_dir
self.required_filenames = self.harbor_certs_filename
if kwargs.get('with_clair'):
self.required_filenames.update(self.clair_certs_filename)
if kwargs.get('with_notary'):
self.required_filenames.update(self.notary_certs_filename)
if kwargs.get('with_chartmuseum'):
self.required_filenames.update(self.chart_museum_filename)
if not kwargs.get('external_database'):
self.required_filenames.update(self.db_certs_filename)
def __getattribute__(self, name: str):
"""
Make the call like 'internal_tls.core_crt_path' possible
"""
# only handle when enabled tls and name ends with 'path'
if name.endswith('_path'):
if not (self.enabled):
return object.__getattribute__(self, name)
name_parts = name.split('_')
if len(name_parts) < 3:
return object.__getattribute__(self, name)
filename = '{}.{}'.format('_'.join(name_parts[:-2]), name_parts[-2])
if filename in self.required_filenames:
return os.path.join(self.data_volume, 'secret', 'tls', filename)
return object.__getattribute__(self, name)
def _check(self, filename: str):
"""
Check the permission of cert and key is correct
"""
path = Path(os.path.join(internal_tls_dir, filename))
if not path.exists:
if filename == 'harbor_internal_ca.crt':
return
raise Exception('File {} not exist'.format(filename))
if not path.is_file:
raise Exception('invalid {}'.format(filename))
# check key file permission
if filename.endswith('.key') and not check_permission(path, mode=0o600):
raise Exception('key file {} permission is not 600'.format(filename))
# check owner can read cert file
if filename.endswith('.crt') and not owner_can_read(path.stat().st_mode):
raise Exception('File {} should readable by owner'.format(filename))
def validate(self) -> bool:
if not self.enabled:
return True
if not internal_tls_dir.exists():
raise Exception('Internal dir for tls {} not exist'.format(internal_tls_dir))
for filename in self.required_filenames:
self._check(filename)
return True
def prepare(self):
"""
Prepare moves certs in tls file to data volume with correct permission.
"""
if not self.enabled:
logging.info('internal tls NOT enabled...')
return
original_tls_dir = get_realpath(self.tls_dir)
rmtree(internal_tls_dir)
if not internal_tls_dir.exists():
os.makedirs(internal_tls_dir)
copytree(original_tls_dir, internal_tls_dir, symlinks=True)
for file in internal_tls_dir.iterdir():
if file.name.endswith('.key'):
file.chmod(0o600)
elif file.name.endswith('.crt'):
file.chmod(0o644)
if file.name in self.db_certs_filename:
os.chown(file, PG_UID, PG_GID)
else:
os.chown(file, DEFAULT_UID, DEFAULT_GID)

View File

@ -1,5 +1,12 @@
## Settings should be set
{%if internal_tls.enabled %}
PORT=9443
TLS_CERT=/etc/harbor/ssl/chartmuseum.crt
TLS_KEY=/etc/harbor/ssl/chartmuseum.key
TLS_CA_CERT=/etc/harbor/ssl/harbor_internal_ca.crt
{% else %}
PORT=9999
{% endif %}
# Only support redis now. If redis is setup, then enable cache
CACHE={{cache_store}}
@ -34,8 +41,6 @@ CHART_URL={{public_url}}/chartrepo
CHART_URL=
{% endif %}
AUTH_ANONYMOUS_GET=false
TLS_CERT=
TLS_KEY=
CONTEXT_PATH=
INDEX_LIMIT=0
MAX_STORAGE_OBJECTS=0

View File

@ -52,3 +52,10 @@ CSRF_KEY={{csrf_key}}
HTTP_PROXY={{core_http_proxy}}
HTTPS_PROXY={{core_https_proxy}}
NO_PROXY={{core_no_proxy}}
{%if internal_tls.enabled %}
INTERNAL_TLS_ENABLED=true
INTERNAL_TLS_KEY_PATH=/etc/harbor/ssl/core.key
INTERNAL_TLS_CERT_PATH=/etc/harbor/ssl/core.crt
INTERNAL_TLS_TRUST_CA_PATH=/etc/harbor/ssl/harbor_internal_ca.crt
{% endif %}

View File

@ -4,7 +4,7 @@ services:
image: goharbor/harbor-log:{{version}}
container_name: harbor-log
restart: always
dns_search: .
dns_search: ""
cap_drop:
- ALL
cap_add:
@ -41,17 +41,23 @@ services:
source: {{gcs_keyfile}}
target: /etc/registry/gcs.key
{% endif %}
{%if registry_custom_ca_bundle_path %}
{%if internal_tls.enabled %}
- type: bind
source: {{registry_custom_ca_bundle_path}}
target: /harbor_cust_cert/custom-ca-bundle.crt
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/tls/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.registry_crt_path}}
target: /etc/harbor/tls/registry.crt
- type: bind
source: {{internal_tls.registry_key_path}}
target: /etc/harbor/tls/registry.key
{% endif %}
networks:
- harbor
{% if with_clair %}
- harbor-clair
{% endif %}
dns_search: .
dns_search: ""
depends_on:
- log
logging:
@ -77,14 +83,20 @@ services:
- type: bind
source: ./common/config/registryctl/config.yml
target: /etc/registryctl/config.yml
{%if registry_custom_ca_bundle_path %}
{%if internal_tls.enabled %}
- type: bind
source: {{registry_custom_ca_bundle_path}}
target: /harbor_cust_cert/custom-ca-bundle.crt
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/ssl/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.registryctl_crt_path}}
target: /etc/harbor/ssl/registryctl.crt
- type: bind
source: {{internal_tls.registryctl_key_path}}
target: /etc/harbor/ssl/registryctl.key
{% endif %}
networks:
- harbor
dns_search: .
dns_search: ""
depends_on:
- log
logging:
@ -106,6 +118,17 @@ services:
- SETUID
volumes:
- {{data_volume}}/database:/var/lib/postgresql/data:z
{%if internal_tls.enabled %}
- type: bind
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/ssl/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.harbor_db_crt_path}}
target: /etc/harbor/ssl/harbor_db.crt
- type: bind
source: {{internal_tls.harbor_db_key_path}}
target: /etc/harbor/ssl/harbor_db.key
{% endif %}
networks:
harbor:
{% if with_notary %}
@ -118,7 +141,7 @@ services:
aliases:
- harbor-db
{% endif %}
dns_search: .
dns_search: ""
env_file:
- ./common/config/db/env
depends_on:
@ -157,6 +180,17 @@ services:
- type: bind
source: {{uaa_ca_file}}
target: /etc/core/certificates/uaa_ca.pem
{% endif %}
{%if internal_tls.enabled %}
- type: bind
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/ssl/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.core_crt_path}}
target: /etc/harbor/ssl/core.crt
- type: bind
source: {{internal_tls.core_key_path}}
target: /etc/harbor/ssl/core.key
{% endif %}
networks:
harbor:
@ -173,7 +207,7 @@ services:
aliases:
- harbor-core
{% endif %}
dns_search: .
dns_search: ""
depends_on:
- log
- registry
@ -201,7 +235,7 @@ services:
- NET_BIND_SERVICE
networks:
- harbor
dns_search: .
dns_search: ""
depends_on:
- log
logging:
@ -227,12 +261,23 @@ services:
- type: bind
source: ./common/config/jobservice/config.yml
target: /etc/jobservice/config.yml
{%if internal_tls.enabled %}
- type: bind
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/ssl/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.job_service_crt_path}}
target: /etc/harbor/ssl/job_service.crt
- type: bind
source: {{internal_tls.job_service_key_path}}
target: /etc/harbor/ssl/job_service.key
{% endif %}
networks:
- harbor
{% if with_clair %}
- harbor-clair
{% endif %}
dns_search: .
dns_search: ""
depends_on:
- core
logging:
@ -265,7 +310,7 @@ services:
aliases:
- redis
{% endif %}
dns_search: .
dns_search: ""
depends_on:
- log
logging:
@ -289,13 +334,24 @@ services:
- ./common/config/nginx:/etc/nginx:z
{% if protocol == 'https' %}
- {{data_volume}}/secret/cert:/etc/cert:z
{% endif %}
{%if internal_tls.enabled %}
- type: bind
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/tls/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.proxy_crt_path}}
target: /etc/harbor/tls/proxy.crt
- type: bind
source: {{internal_tls.proxy_key_path}}
target: /etc/harbor/tls/proxy.key
{% endif %}
networks:
- harbor
{% if with_notary %}
- harbor-notary
{% endif %}
dns_search: .
dns_search: ""
ports:
- {{http_port}}:8080
{% if protocol == 'https' %}
@ -322,7 +378,7 @@ services:
networks:
- notary-sig
- harbor-notary
dns_search: .
dns_search: ""
volumes:
- ./common/config/notary:/etc/notary:z
- type: bind
@ -331,6 +387,17 @@ services:
- type: bind
source: {{data_volume}}/secret/registry/root.crt
target: /etc/notary/root.crt
{%if internal_tls.enabled %}
- type: bind
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/ssl/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.notary_server_crt_path}}
target: /etc/harbor/ssl/notary_server.crt
- type: bind
source: {{internal_tls.notary_server_key_path}}
target: /etc/harbor/ssl/notary_server.key
{% endif %}
env_file:
- ./common/config/notary/server_env
depends_on:
@ -352,7 +419,7 @@ services:
notary-sig:
aliases:
- notarysigner
dns_search: .
dns_search: ""
volumes:
- ./common/config/notary:/etc/notary:z
- type: bind
@ -361,6 +428,17 @@ services:
- type: bind
source: {{data_volume}}/secret/notary/notary-signer.key
target: /etc/notary/notary-signer.key
{%if internal_tls.enabled %}
- type: bind
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/ssl/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.notary_signer_crt_path}}
target: /etc/harbor/ssl/notary_signer.crt
- type: bind
source: {{internal_tls.notary_signer_key_path}}
target: /etc/harbor/ssl/notary_signer.key
{% endif %}
env_file:
- ./common/config/notary/signer_env
depends_on:
@ -388,7 +466,7 @@ services:
- SETGID
- SETUID
cpu_quota: 50000
dns_search: .
dns_search: ""
depends_on:
- log
{% if external_database == False %}
@ -398,11 +476,17 @@ services:
- type: bind
source: ./common/config/clair/config.yaml
target: /etc/clair/config.yaml
{%if registry_custom_ca_bundle_path %}
{%if internal_tls.enabled %}
- type: bind
source: {{registry_custom_ca_bundle_path}}
target: /harbor_cust_cert/custom-ca-bundle.crt
{% endif %}
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/ssl/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.clair_crt_path}}
target: /etc/harbor/ssl/clair.crt
- type: bind
source: {{internal_tls.clair_key_path}}
target: /etc/harbor/ssl/clair.key
{% endif %}
logging:
driver: "syslog"
options:
@ -423,11 +507,22 @@ services:
- SETGID
- SETUID
cpu_quota: 50000
dns_search: .
dns_search: ""
depends_on:
- clair
{% if external_redis == False %}
- redis
{% endif %}
{%if internal_tls.enabled %}
- type: bind
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/ssl/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.clair_adapter_crt_path}}
target: /etc/harbor/ssl/clair_adapter.crt
- type: bind
source: {{internal_tls.clair_adapter_key_path}}
target: /etc/harbor/ssl/clair_adapter.key
{% endif %}
logging:
driver: "syslog"
@ -480,21 +575,27 @@ services:
- SETUID
networks:
- harbor-chartmuseum
dns_search: .
dns_search: ""
depends_on:
- log
volumes:
- {{data_volume}}/chart_storage:/chart_storage:z
- ./common/config/chartserver:/etc/chartserver:z
{%if internal_tls.enabled %}
- type: bind
source: {{internal_tls.harbor_internal_ca_crt_path}}
target: /etc/harbor/ssl/harbor_internal_ca.crt
- type: bind
source: {{internal_tls.chartmuseum_crt_path}}
target: /etc/harbor/ssl/chartmuseum.crt
- type: bind
source: {{internal_tls.chartmuseum_key_path}}
target: /etc/harbor/ssl/chartmuseum.key
{% endif %}
{% if gcs_keyfile %}
- type: bind
source: {{gcs_keyfile}}
target: /etc/chartserver/gcs.key
{% endif %}
{%if registry_custom_ca_bundle_path %}
- type: bind
source: {{registry_custom_ca_bundle_path}}
target: /harbor_cust_cert/custom-ca-bundle.crt
{% endif %}
logging:
driver: "syslog"

View File

@ -1,14 +1,20 @@
---
#Protocol used to serve
protocol: "http"
{% if internal_tls.enabled %}
protocol: "https"
#Config certification if use 'https' protocol
#https_config:
# cert: "server.crt"
# key: "server.key"
https_config:
cert: "/etc/harbor/ssl/job_service.crt"
key: "/etc/harbor/ssl/job_service.key"
#Server listening port
port: 8443
{% else %}
protocol: "http"
#Server listening port
port: 8080
{% endif %}
#Worker pool
worker_pool:

View File

@ -1,10 +1,18 @@
CORE_SECRET={{core_secret}}
JOBSERVICE_SECRET={{jobservice_secret}}
CORE_URL={{core_url}}
REGISTRY_CONTROLLER_URL={{registry_controller_url}}
JOBSERVICE_WEBHOOK_JOB_MAX_RETRY={{notification_webhook_job_max_retry}}
{%if internal_tls.enabled %}
INTERNAL_TLS_ENABLED=true
INTERNAL_TLS_TRUST_CA_PATH=/etc/harbor/ssl/harbor_internal_ca.crt
INTERNAL_TLS_KEY_PATH=/etc/harbor/ssl/job_service.key
INTERNAL_TLS_CERT_PATH=/etc/harbor/ssl/job_service.crt
{% endif %}
HTTP_PROXY={{jobservice_http_proxy}}
HTTPS_PROXY={{jobservice_https_proxy}}
NO_PROXY={{jobservice_no_proxy}}
REGISTRY_CREDENTIAL_USERNAME={{registry_username}}
REGISTRY_CREDENTIAL_PASSWORD={{registry_password}}
REGISTRY_CREDENTIAL_PASSWORD={{registry_password}}

View File

@ -20,7 +20,11 @@ http {
proxy_http_version 1.1;
upstream core {
{% if internal_tls.enabled %}
server core:10443;
{% else %}
server core:8080;
{% endif %}
}
upstream portal {
@ -80,7 +84,18 @@ http {
}
location /c/ {
{% if internal_tls.enabled %}
proxy_pass https://core/c/;
proxy_ssl_certificate /etc/harbor/tls/proxy.crt;
proxy_ssl_certificate_key /etc/harbor/tls/proxy.key;
proxy_ssl_trusted_certificate /etc/harbor/tls/harbor_internal_ca.crt;
proxy_ssl_verify_depth 2;
proxy_ssl_verify on;
proxy_ssl_session_reuse on;
{% else %}
proxy_pass http://core/c/;
{% endif %}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@ -95,7 +110,18 @@ http {
}
location /api/ {
{% if internal_tls.enabled %}
proxy_pass https://core/api/;
proxy_ssl_certificate /etc/harbor/tls/proxy.crt;
proxy_ssl_certificate_key /etc/harbor/tls/proxy.key;
proxy_ssl_trusted_certificate /etc/harbor/tls/harbor_internal_ca.crt;
proxy_ssl_verify_depth 2;
proxy_ssl_verify on;
proxy_ssl_session_reuse on;
{% else %}
proxy_pass http://core/api/;
{% endif %}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@ -110,7 +136,18 @@ http {
}
location /chartrepo/ {
{% if internal_tls.enabled %}
proxy_pass https://core/chartrepo/;
proxy_ssl_certificate /etc/harbor/tls/proxy.crt;
proxy_ssl_certificate_key /etc/harbor/tls/proxy.key;
proxy_ssl_trusted_certificate /etc/harbor/tls/harbor_internal_ca.crt;
proxy_ssl_verify_depth 2;
proxy_ssl_verify on;
proxy_ssl_session_reuse on;
{% else %}
proxy_pass http://core/chartrepo/;
{% endif %}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@ -129,7 +166,18 @@ http {
}
location /v2/ {
{% if internal_tls.enabled %}
proxy_pass https://core/v2/;
proxy_ssl_certificate /etc/harbor/tls/proxy.crt;
proxy_ssl_certificate_key /etc/harbor/tls/proxy.key;
proxy_ssl_trusted_certificate /etc/harbor/tls/harbor_internal_ca.crt;
proxy_ssl_verify_depth 2;
proxy_ssl_verify on;
proxy_ssl_session_reuse on;
{% else %}
proxy_pass http://core/v2/;
{% endif %}
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@ -141,7 +189,18 @@ http {
}
location /service/ {
{% if internal_tls.enabled %}
proxy_pass https://core/service/;
proxy_ssl_certificate /etc/harbor/tls/proxy.crt;
proxy_ssl_certificate_key /etc/harbor/tls/proxy.key;
proxy_ssl_trusted_certificate /etc/harbor/tls/harbor_internal_ca.crt;
proxy_ssl_verify_depth 2;
proxy_ssl_verify on;
proxy_ssl_session_reuse on;
{% else %}
proxy_pass http://core/service/;
{% endif %}
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

View File

@ -1,8 +1,14 @@
---
{% if internal_tls.enabled %}
protocol: "https"
port: 8443
https_config:
cert: "/etc/harbor/ssl/registryctl.crt"
key: "/etc/harbor/ssl/registryctl.key"
{% else %}
protocol: "http"
port: 8080
{% endif %}
log_level: "INFO"
#https_config:
# cert: "server.crt"
# key: "server.key"

View File

@ -1,3 +1,8 @@
CORE_SECRET={{core_secret}}
JOBSERVICE_SECRET={{jobservice_secret}}
{%if internal_tls.enabled %}
INTERNAL_TLS_ENABLED=true
INTERNAL_TLS_TRUST_CA_PATH=/etc/harbor/ssl/harbor_internal_ca.crt
INTERNAL_TLS_KEY_PATH=/etc/harbor/ssl/registryctl.key
INTERNAL_TLS_CERT_PATH=/etc/harbor/ssl/registryctl.crt
{% endif %}

View File

@ -3,12 +3,13 @@ import os, subprocess, shutil
from pathlib import Path
from subprocess import DEVNULL
from g import DEFAULT_GID, DEFAULT_UID
from g import DEFAULT_GID, DEFAULT_UID, trust_ca_dir, storage_ca_bundle_filename
from .misc import (
mark_file,
generate_random_string,
check_permission,
stat_decorator)
stat_decorator,
get_realpath)
SSL_CERT_PATH = os.path.join("/etc/cert", "server.crt")
SSL_CERT_KEY_PATH = os.path.join("/etc/cert", "server.key")
@ -72,7 +73,7 @@ def openssl_installed():
return True
def prepare_ca(
def prepare_registry_ca(
private_key_pem_path: Path,
root_crt_path: Path,
old_private_key_pem_path: Path,
@ -97,4 +98,36 @@ def prepare_ca(
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)
os.chown(private_key_pem_path, DEFAULT_UID, DEFAULT_GID)
def prepare_trust_ca(**kwargs):
def f(path: str, file_name: str):
# check if source file valied
src_path = kwargs.get(path)
if not src_path:
return
real_path = get_realpath(src_path)
if not real_path.exists():
raise Exception('ca file {} is not exist'.format(real_path))
if not real_path.is_file():
raise Exception('{} is not file'.format(real_path))
dst_path = trust_ca_dir.joinpath(file_name)
# check destination dir exist
if not trust_ca_dir.exists():
trust_ca_dir.mkdir(parents=True)
else:
os.remove(dst_path)
# copy src to dst
shutil.copy(src_path, dst_path)
# change ownership and permission
mark_file(dst_path)
for p in (
('internal_https_ca_path', 'harbor_internal_ca.crt'),
('registry_custom_ca_bundle_path', storage_ca_bundle_filename)):
f(*p)

View File

@ -105,4 +105,5 @@ def prepare_chartmuseum(config_dict):
storage_driver=storage_driver,
all_storage_driver_configs=all_storage_provider_configs,
public_url=config_dict['public_url'],
chart_absolute_url=config_dict['chart_absolute_url'])
chart_absolute_url=config_dict['chart_absolute_url'],
internal_tls=config_dict['internal_tls'])

View File

@ -1,6 +1,8 @@
import os
import yaml
import logging
from models import InternalTLS
from g import versions_file_path, host_root_dir, DEFAULT_UID, INTERNAL_NO_PROXY_DN
from utils.misc import generate_random_string, owner_can_read, other_can_read
@ -104,12 +106,12 @@ def parse_yaml_config(config_file_path, with_notary, with_clair, with_trivy, wit
configs = yaml.load(f)
config_dict = {
'adminserver_url': "http://adminserver:8080",
'registry_url': "http://registry:5000",
'registry_controller_url': "http://registryctl:8080",
'core_url': "http://core:8080",
'core_local_url': "http://127.0.0.1:8080",
'token_service_url': "http://core:8080/service/token",
'adminserver_url': 'http://adminserver:8080',
'registry_url': 'http://registry:5000',
'registry_controller_url': 'http://registryctl:8080',
'core_url': 'http://core:8080',
'core_local_url': 'http://127.0.0.1:8080',
'token_service_url': 'http://core:8080/service/token',
'jobservice_url': 'http://jobservice:8080',
'clair_url': 'http://clair:6060',
'clair_adapter_url': 'http://clair-adapter:8080',
@ -333,6 +335,27 @@ def parse_yaml_config(config_file_path, with_notary, with_clair, with_trivy, wit
config_dict['registry_username'] = REGISTRY_USER_NAME
config_dict['registry_password'] = generate_random_string(32)
# TLS related configs
if configs.get('internal_tls'):
config_dict['internal_tls'] = InternalTLS(
configs['internal_tls'],
configs['data_volume'],
with_notary=with_notary,
with_clair=with_clair,
with_chartmuseum=with_chartmuseum,
external_database=config_dict['external_database'])
if config_dict['internal_tls'].enabled:
config_dict['registry_controller_url'] = 'https://registryctl:8443'
config_dict['core_url'] = 'https://core:10443'
config_dict['core_local_url'] = 'https://127.0.0.1:10443'
config_dict['token_service_url'] = 'https://core:10443/service/token'
config_dict['jobservice_url'] = 'https://jobservice:8443'
# config_dict['clair_adapter_url'] = 'https://clair-adapter:8443'
# config_dict['notary_url'] = 'https://notary-server:4443'
config_dict['chart_repository_url'] = 'https://chartmuseum:9443'
return config_dict

View File

@ -1,4 +1,5 @@
import os
from functools import reduce
from g import templates_dir
from .configs import parse_versions
@ -25,7 +26,6 @@ def prepare_docker_compose(configs, with_clair, with_trivy, with_notary, with_ch
'log_location': configs['log_location'],
'protocol': configs['protocol'],
'http_port': configs['http_port'],
'registry_custom_ca_bundle_path': configs['registry_custom_ca_bundle_path'],
'external_redis': configs['external_redis'],
'external_database': configs['external_database'],
'with_notary': with_notary,
@ -34,6 +34,10 @@ def prepare_docker_compose(configs, with_clair, with_trivy, with_notary, with_ch
'with_chartmuseum': with_chartmuseum
}
# if configs.get('registry_custom_ca_bundle_path'):
# rendering_variables['registry_custom_ca_bundle_path'] = configs.get('registry_custom_ca_bundle_path')
# rendering_variables['custom_ca_required'] = True
# for gcs
storage_config = configs.get('storage_provider_config') or {}
if storage_config.get('keyfile') and configs['storage_provider_name'] == 'gcs':
@ -45,6 +49,9 @@ def prepare_docker_compose(configs, with_clair, with_trivy, with_notary, with_ch
rendering_variables['cert_path'] = configs['cert_path']
rendering_variables['https_port'] = configs['https_port']
# internal cert pairs
rendering_variables['internal_tls'] = configs['internal_tls']
# for uaa
uaa_config = configs.get('uaa') or {}
if uaa_config.get('ca_file'):

View File

@ -0,0 +1,4 @@
def prepare_tls(config_dict):
config_dict['internal_tls'].prepare()
config_dict['internal_tls'].validate()

View File

@ -30,6 +30,7 @@ def prepare_job_service(config_dict):
jobservice_conf,
uid=DEFAULT_UID,
gid=DEFAULT_GID,
internal_tls=config_dict['internal_tls'],
max_job_workers=config_dict['max_job_workers'],
redis_url=config_dict['redis_url_js'],
level=log_level)

View File

@ -3,7 +3,7 @@ import secrets
from pathlib import Path
from functools import wraps
from g import DEFAULT_UID, DEFAULT_GID
from g import DEFAULT_UID, DEFAULT_GID, host_root_dir
# To meet security requirement
# By default it will change file mode to 0600, and make the owner of the file to 10000:10000
@ -168,3 +168,12 @@ def stat_decorator(func):
return check_wrapper
def get_realpath(path: str) -> Path:
"""
Return the real path in your host if you mounted your host's filesystem to /hostfs,
or return the original path
"""
if os.path.isdir(host_root_dir):
return os.path.join(host_root_dir, path.lstrip('/'))
return Path(path)

View File

@ -61,7 +61,8 @@ def render_nginx_template(config_dict):
gid=DEFAULT_GID,
https_redirect='$host' + ('https_port' in config_dict and (":" + str(config_dict['https_port'])) or ""),
ssl_cert=SSL_CERT_PATH,
ssl_cert_key=SSL_CERT_KEY_PATH)
ssl_cert_key=SSL_CERT_KEY_PATH,
internal_tls=config_dict['internal_tls'])
location_file_pattern = CUSTOM_NGINX_LOCATION_FILE_PATTERN_HTTPS
else:
@ -69,7 +70,8 @@ def render_nginx_template(config_dict):
nginx_http_conf_template,
nginx_conf,
uid=DEFAULT_UID,
gid=DEFAULT_GID)
gid=DEFAULT_GID,
internal_tls=config_dict['internal_tls'])
location_file_pattern = CUSTOM_NGINX_LOCATION_FILE_PATTERN_HTTP
copy_nginx_location_configs_if_exist(nginx_template_ext_dir, nginx_confd_dir, location_file_pattern)

View File

@ -1,6 +1,6 @@
import os, shutil
from g import config_dir, templates_dir
from g import config_dir, templates_dir, DEFAULT_GID, DEFAULT_UID
from utils.misc import prepare_dir
from utils.jinja import render_jinja
@ -12,19 +12,18 @@ registryctl_conf_env = os.path.join(config_dir, "registryctl", "env")
def prepare_registry_ctl(config_dict):
# prepare dir
prepare_registry_ctl_config_dir()
prepare_dir(registryctl_config_dir)
# Render Registryctl
# Render Registryctl env
render_jinja(
registryctl_env_template_path,
registryctl_conf_env,
**config_dict)
# Copy Registryctl config
copy_registry_ctl_conf(registryctl_config_template_path, registryctl_conf)
def prepare_registry_ctl_config_dir():
prepare_dir(registryctl_config_dir)
def copy_registry_ctl_conf(src, dst):
shutil.copyfile(src, dst)
# Render Registryctl config
render_jinja(
registryctl_config_template_path,
registryctl_conf,
uid=DEFAULT_UID,
gid=DEFAULT_GID,
**config_dict)

View File

@ -55,7 +55,6 @@ 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 \
-v /:/hostfs:z \
goharbor/prepare:dev $@