diff options
5 files changed, 367 insertions, 0 deletions
diff --git a/recipes-containers/docker-registry/docker-registry_git.bb b/recipes-containers/docker-registry/docker-registry_git.bb new file mode 100644 index 00000000..8b42d798 --- /dev/null +++ b/recipes-containers/docker-registry/docker-registry_git.bb | |||
@@ -0,0 +1,92 @@ | |||
1 | HOMEPAGE = "https://github.com/docker/docker-registry" | ||
2 | SUMMARY = "Registry server for Docker" | ||
3 | DESCRIPTION = "\ | ||
4 | This is the classic python docker-registry. \ | ||
5 | . \ | ||
6 | hosting/delivering of repositories and images \ | ||
7 | " | ||
8 | |||
9 | SRCREV = "fd8c0c114985547b69088e0f1526e58bfe2ff914" | ||
10 | SRC_URI = "\ | ||
11 | git://github.com/docker/docker-registry.git \ | ||
12 | file://docker-registry.conf \ | ||
13 | file://docker-registry.service \ | ||
14 | file://config.yml \ | ||
15 | file://change_sqlalchemy_rqt.patch \ | ||
16 | " | ||
17 | |||
18 | LICENSE = "Apache-2.0" | ||
19 | LIC_FILES_CHKSUM = "file://LICENSE;md5=35e8e5305c1b7b4a5761f9de5d44e5f4" | ||
20 | |||
21 | S = "${WORKDIR}/git" | ||
22 | |||
23 | PV = "0.9.1+git${SRCREV}" | ||
24 | |||
25 | RDEPENDS_${PN} += "\ | ||
26 | docker \ | ||
27 | gunicorn (= 19.1.1) \ | ||
28 | python-pip \ | ||
29 | python-distribute \ | ||
30 | python-m2crypto (= 0.22.3) \ | ||
31 | python-pyyaml (= 3.11) \ | ||
32 | python-flask (= 0.10.1) \ | ||
33 | python-gevent (= 1.0.1) \ | ||
34 | python-requests (= 2.3.0) \ | ||
35 | python-sqlalchemy (>= 0.9.4) \ | ||
36 | python-blinker (= 1.3) \ | ||
37 | python-backports-lzma (= 0.0.3) \ | ||
38 | python-flask-cors (= 1.10.3) \ | ||
39 | python-bugsnag (= 2.0.2) \ | ||
40 | python-docker-registry-core (= 2.0.3) \ | ||
41 | python-newrelic (= 2.22.0.19) \ | ||
42 | python-itsdangerous (>= 0.21) \ | ||
43 | python-jinja2 (>= 2.4) \ | ||
44 | python-werkzeug (>= 0.7) \ | ||
45 | python-simplejson (= 3.6.2) \ | ||
46 | python-redis (= 2.10.3) \ | ||
47 | python-boto (= 2.34.0) \ | ||
48 | python-webob \ | ||
49 | " | ||
50 | # OFFICIAL REQ: | ||
51 | # docker-registry-core>=2,<3 | ||
52 | # blinker==1.3 | ||
53 | # backports.lzma==0.0.3,!=0.0.4 | ||
54 | |||
55 | # Flask==0.10.1 | ||
56 | # gevent==1.0.1 | ||
57 | # gunicorn==19.1.1 | ||
58 | # PyYAML==3.11 | ||
59 | # requests==2.3.0 | ||
60 | # M2Crypto==0.22.3 | ||
61 | # sqlalchemy==0.9.4 | ||
62 | # setuptools==5.8 | ||
63 | # | ||
64 | # [bugsnag] | ||
65 | # bugsnag>=2.0,<2.1 | ||
66 | # | ||
67 | # [cors] | ||
68 | # Flask-cors>=1.8,<2.0 | ||
69 | # | ||
70 | # [newrelic] | ||
71 | # newrelic>=2.22,<2.23 | ||
72 | |||
73 | |||
74 | inherit setuptools systemd | ||
75 | |||
76 | SYSTEMD_PACKAGES = "${@base_contains('DISTRO_FEATURES','systemd','${PN}','',d)}" | ||
77 | SYSTEMD_SERVICE_${PN} = "${@base_contains('DISTRO_FEATURES','systemd','docker-registry.service','',d)}" | ||
78 | |||
79 | do_install_append() { | ||
80 | mkdir -p ${D}/etc/default/ | ||
81 | cp ${WORKDIR}/docker-registry.conf ${D}/etc/default/docker-registry | ||
82 | |||
83 | if ${@base_contains('DISTRO_FEATURES','systemd','true','false',d)}; then | ||
84 | install -d ${D}${systemd_unitdir}/system | ||
85 | install -m 644 ${WORKDIR}/docker-registry.service ${D}/${systemd_unitdir}/system | ||
86 | fi | ||
87 | # based on config_mirror.yml - uses /var/docker-registry instead of /tmp for files | ||
88 | install ${WORKDIR}/config.yml ${D}/etc/docker-registry.yml | ||
89 | mkdir -p ${D}/var/docker-registry | ||
90 | } | ||
91 | |||
92 | FILES_${PN} += "/etc/default /var/docker-registry /etc/ /etc/default/volatiles" | ||
diff --git a/recipes-containers/docker-registry/files/change_sqlalchemy_rqt.patch b/recipes-containers/docker-registry/files/change_sqlalchemy_rqt.patch new file mode 100644 index 00000000..75cbd6df --- /dev/null +++ b/recipes-containers/docker-registry/files/change_sqlalchemy_rqt.patch | |||
@@ -0,0 +1,13 @@ | |||
1 | --- | ||
2 | requirements/main.txt | 2 +- | ||
3 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
4 | |||
5 | --- a/requirements/main.txt | ||
6 | +++ b/requirements/main.txt | ||
7 | @@ -5,5 +5,5 @@ | ||
8 | PyYAML==3.11 | ||
9 | requests==2.3.0 | ||
10 | M2Crypto==0.22.3 | ||
11 | -sqlalchemy==0.9.4 | ||
12 | +sqlalchemy>=0.9.4 | ||
13 | setuptools==5.8 | ||
diff --git a/recipes-containers/docker-registry/files/config.yml b/recipes-containers/docker-registry/files/config.yml new file mode 100644 index 00000000..8b33766f --- /dev/null +++ b/recipes-containers/docker-registry/files/config.yml | |||
@@ -0,0 +1,228 @@ | |||
1 | # All other flavors inherit the `common' config snippet | ||
2 | common: &common | ||
3 | issue: '"docker-registry server"' | ||
4 | # Default log level is info | ||
5 | loglevel: _env:LOGLEVEL:info | ||
6 | # Enable debugging (additional informations in the output of the _ping endpoint) | ||
7 | debug: _env:DEBUG:false | ||
8 | # By default, the registry acts standalone (eg: doesn't query the index) | ||
9 | standalone: _env:STANDALONE:true | ||
10 | # The default endpoint to use (if NOT standalone) is index.docker.io | ||
11 | index_endpoint: _env:INDEX_ENDPOINT:https://index.docker.io | ||
12 | # Storage redirect is disabled | ||
13 | storage_redirect: _env:STORAGE_REDIRECT | ||
14 | # Token auth is enabled (if NOT standalone) | ||
15 | disable_token_auth: _env:DISABLE_TOKEN_AUTH | ||
16 | # No priv key | ||
17 | privileged_key: _env:PRIVILEGED_KEY | ||
18 | # No search backend | ||
19 | search_backend: _env:SEARCH_BACKEND | ||
20 | # SQLite search backend | ||
21 | sqlalchemy_index_database: _env:SQLALCHEMY_INDEX_DATABASE:sqlite:////var/docker-registry/docker-registry.db | ||
22 | |||
23 | # Mirroring is not enabled | ||
24 | mirroring: | ||
25 | source: _env:MIRROR_SOURCE # https://registry-1.docker.io | ||
26 | source_index: _env:MIRROR_SOURCE_INDEX # https://index.docker.io | ||
27 | tags_cache_ttl: _env:MIRROR_TAGS_CACHE_TTL:172800 # seconds | ||
28 | |||
29 | cache: | ||
30 | host: _env:CACHE_REDIS_HOST | ||
31 | port: _env:CACHE_REDIS_PORT | ||
32 | db: _env:CACHE_REDIS_DB:0 | ||
33 | password: _env:CACHE_REDIS_PASSWORD | ||
34 | |||
35 | # Enabling LRU cache for small files | ||
36 | # This speeds up read/write on small files | ||
37 | # when using a remote storage backend (like S3). | ||
38 | cache_lru: | ||
39 | host: _env:CACHE_LRU_REDIS_HOST | ||
40 | port: _env:CACHE_LRU_REDIS_PORT | ||
41 | db: _env:CACHE_LRU_REDIS_DB:0 | ||
42 | password: _env:CACHE_LRU_REDIS_PASSWORD | ||
43 | |||
44 | # Enabling these options makes the Registry send an email on each code Exception | ||
45 | email_exceptions: | ||
46 | smtp_host: _env:SMTP_HOST | ||
47 | smtp_port: _env:SMTP_PORT:25 | ||
48 | smtp_login: _env:SMTP_LOGIN | ||
49 | smtp_password: _env:SMTP_PASSWORD | ||
50 | smtp_secure: _env:SMTP_SECURE:false | ||
51 | from_addr: _env:SMTP_FROM_ADDR:docker-registry@localdomain.local | ||
52 | to_addr: _env:SMTP_TO_ADDR:noise+dockerregistry@localdomain.local | ||
53 | |||
54 | # Enable bugsnag (set the API key) | ||
55 | bugsnag: _env:BUGSNAG | ||
56 | |||
57 | # CORS support is not enabled by default | ||
58 | cors: | ||
59 | origins: _env:CORS_ORIGINS | ||
60 | methods: _env:CORS_METHODS | ||
61 | headers: _env:CORS_HEADERS:[Content-Type] | ||
62 | expose_headers: _env:CORS_EXPOSE_HEADERS | ||
63 | supports_credentials: _env:CORS_SUPPORTS_CREDENTIALS | ||
64 | max_age: _env:CORS_MAX_AGE | ||
65 | send_wildcard: _env:CORS_SEND_WILDCARD | ||
66 | always_send: _env:CORS_ALWAYS_SEND | ||
67 | automatic_options: _env:CORS_AUTOMATIC_OPTIONS | ||
68 | vary_header: _env:CORS_VARY_HEADER | ||
69 | resources: _env:CORS_RESOURCES | ||
70 | |||
71 | local: &local | ||
72 | <<: *common | ||
73 | storage: local | ||
74 | storage_path: _env:STORAGE_PATH:/var/docker-registry | ||
75 | |||
76 | |||
77 | s3: &s3 | ||
78 | <<: *common | ||
79 | storage: s3 | ||
80 | s3_region: _env:AWS_REGION | ||
81 | s3_bucket: _env:AWS_BUCKET | ||
82 | boto_bucket: _env:AWS_BUCKET | ||
83 | storage_path: _env:STORAGE_PATH:/registry | ||
84 | s3_encrypt: _env:AWS_ENCRYPT:true | ||
85 | s3_secure: _env:AWS_SECURE:true | ||
86 | s3_access_key: _env:AWS_KEY | ||
87 | s3_secret_key: _env:AWS_SECRET | ||
88 | s3_use_sigv4: _env:AWS_USE_SIGV4 | ||
89 | boto_host: _env:AWS_HOST | ||
90 | boto_port: _env:AWS_PORT | ||
91 | boto_calling_format: _env:AWS_CALLING_FORMAT | ||
92 | |||
93 | cloudfronts3: &cloudfronts3 | ||
94 | <<: *s3 | ||
95 | cloudfront: | ||
96 | base: _env:CF_BASE_URL | ||
97 | keyid: _env:CF_KEYID | ||
98 | keysecret: _env:CF_KEYSECRET | ||
99 | |||
100 | azureblob: &azureblob | ||
101 | <<: *common | ||
102 | storage: azureblob | ||
103 | azure_storage_account_name: _env:AZURE_STORAGE_ACCOUNT_NAME | ||
104 | azure_storage_account_key: _env:AZURE_STORAGE_ACCOUNT_KEY | ||
105 | azure_storage_container: _env:AZURE_STORAGE_CONTAINER:registry | ||
106 | azure_use_https: _env:AZURE_USE_HTTPS:true | ||
107 | |||
108 | # Ceph Object Gateway Configuration | ||
109 | # See http://ceph.com/docs/master/radosgw/ for details on installing this service. | ||
110 | ceph-s3: &ceph-s3 | ||
111 | <<: *common | ||
112 | storage: s3 | ||
113 | s3_region: ~ | ||
114 | s3_bucket: _env:AWS_BUCKET | ||
115 | s3_encrypt: _env:AWS_ENCRYPT:false | ||
116 | s3_secure: _env:AWS_SECURE:false | ||
117 | storage_path: _env:STORAGE_PATH:/registry | ||
118 | s3_access_key: _env:AWS_KEY | ||
119 | s3_secret_key: _env:AWS_SECRET | ||
120 | boto_bucket: _env:AWS_BUCKET | ||
121 | boto_host: _env:AWS_HOST | ||
122 | boto_port: _env:AWS_PORT | ||
123 | boto_debug: _env:AWS_DEBUG:0 | ||
124 | boto_calling_format: _env:AWS_CALLING_FORMAT | ||
125 | |||
126 | # Google Cloud Storage Configuration | ||
127 | # See: | ||
128 | # https://developers.google.com/storage/docs/reference/v1/getting-startedv1#keys | ||
129 | # for details on access and secret keys. | ||
130 | gcs: | ||
131 | <<: *common | ||
132 | storage: gcs | ||
133 | boto_bucket: _env:GCS_BUCKET | ||
134 | storage_path: _env:STORAGE_PATH:/registry | ||
135 | gs_secure: _env:GCS_SECURE:true | ||
136 | gs_access_key: _env:GCS_KEY | ||
137 | gs_secret_key: _env:GCS_SECRET | ||
138 | # OAuth 2.0 authentication with the storage. | ||
139 | # oauth2 can be set to true or false. If it is set to true, gs_access_key, | ||
140 | # gs_secret_key and gs_secure are not needed. | ||
141 | # Client ID and Client Secret must be set into OAUTH2_CLIENT_ID and | ||
142 | # OAUTH2_CLIENT_SECRET environment variables. | ||
143 | # See: https://developers.google.com/accounts/docs/OAuth2. | ||
144 | oauth2: _env:GCS_OAUTH2:false | ||
145 | |||
146 | # This flavor is for storing images in Openstack Swift | ||
147 | swift: &swift | ||
148 | <<: *common | ||
149 | storage: swift | ||
150 | storage_path: _env:STORAGE_PATH:/registry | ||
151 | # keystone authorization | ||
152 | swift_authurl: _env:OS_AUTH_URL | ||
153 | swift_container: _env:OS_CONTAINER | ||
154 | swift_user: _env:OS_USERNAME | ||
155 | swift_password: _env:OS_PASSWORD | ||
156 | swift_tenant_name: _env:OS_TENANT_NAME | ||
157 | swift_region_name: _env:OS_REGION_NAME | ||
158 | |||
159 | # This flavor stores the images in Glance (to integrate with openstack) | ||
160 | # See also: https://github.com/docker/openstack-docker | ||
161 | glance: &glance | ||
162 | <<: *common | ||
163 | storage: glance | ||
164 | storage_alternate: _env:GLANCE_STORAGE_ALTERNATE:file | ||
165 | storage_path: _env:STORAGE_PATH:/var/docker-registry | ||
166 | |||
167 | openstack: | ||
168 | <<: *glance | ||
169 | |||
170 | # This flavor stores the images in Glance (to integrate with openstack) | ||
171 | # and tags in Swift. | ||
172 | glance-swift: &glance-swift | ||
173 | <<: *swift | ||
174 | storage: glance | ||
175 | storage_alternate: swift | ||
176 | |||
177 | openstack-swift: | ||
178 | <<: *glance-swift | ||
179 | |||
180 | elliptics: | ||
181 | <<: *common | ||
182 | storage: elliptics | ||
183 | elliptics_nodes: _env:ELLIPTICS_NODES | ||
184 | elliptics_wait_timeout: _env:ELLIPTICS_WAIT_TIMEOUT:60 | ||
185 | elliptics_check_timeout: _env:ELLIPTICS_CHECK_TIMEOUT:60 | ||
186 | elliptics_io_thread_num: _env:ELLIPTICS_IO_THREAD_NUM:2 | ||
187 | elliptics_net_thread_num: _env:ELLIPTICS_NET_THREAD_NUM:2 | ||
188 | elliptics_nonblocking_io_thread_num: _env:ELLIPTICS_NONBLOCKING_IO_THREAD_NUM:2 | ||
189 | elliptics_groups: _env:ELLIPTICS_GROUPS | ||
190 | elliptics_verbosity: _env:ELLIPTICS_VERBOSITY:4 | ||
191 | elliptics_logfile: _env:ELLIPTICS_LOGFILE:/dev/stderr | ||
192 | elliptics_addr_family: _env:ELLIPTICS_ADDR_FAMILY:2 | ||
193 | |||
194 | # This flavor stores the images in Aliyun OSS | ||
195 | # See: | ||
196 | # https://i.aliyun.com/access_key/ | ||
197 | # for details on access and secret keys. | ||
198 | oss: &oss | ||
199 | <<: *common | ||
200 | storage: oss | ||
201 | storage_path: _env:STORAGE_PATH:/registry/ | ||
202 | oss_host: _env:OSS_HOST | ||
203 | oss_bucket: _env:OSS_BUCKET | ||
204 | oss_accessid: _env:OSS_KEY | ||
205 | oss_accesskey: _env:OSS_SECRET | ||
206 | |||
207 | |||
208 | |||
209 | # This is the default configuration when no flavor is specified | ||
210 | dev: &dev | ||
211 | <<: *local | ||
212 | loglevel: _env:LOGLEVEL:debug | ||
213 | debug: _env:DEBUG:true | ||
214 | search_backend: _env:SEARCH_BACKEND:sqlalchemy | ||
215 | |||
216 | # This flavor is used by unit tests | ||
217 | test: | ||
218 | <<: *dev | ||
219 | index_endpoint: https://registry-stage.hub.docker.com | ||
220 | standalone: true | ||
221 | storage_path: _env:STORAGE_PATH:./tmp/test | ||
222 | |||
223 | # To specify another flavor, set the environment variable SETTINGS_FLAVOR | ||
224 | # $ export SETTINGS_FLAVOR=prod | ||
225 | prod: | ||
226 | <<: *s3 | ||
227 | storage_path: _env:STORAGE_PATH:/prod | ||
228 | |||
diff --git a/recipes-containers/docker-registry/files/docker-registry.conf b/recipes-containers/docker-registry/files/docker-registry.conf new file mode 100644 index 00000000..940ece1d --- /dev/null +++ b/recipes-containers/docker-registry/files/docker-registry.conf | |||
@@ -0,0 +1,19 @@ | |||
1 | # The Docker registry configuration file | ||
2 | DOCKER_REGISTRY_CONFIG=/etc/docker-registry.yml | ||
3 | |||
4 | # The configuration to use from DOCKER_REGISTRY_CONFIG file | ||
5 | SETTINGS_FLAVOR=local | ||
6 | |||
7 | # Address to bind the registry to | ||
8 | REGISTRY_ADDRESS=0.0.0.0 | ||
9 | |||
10 | # Port to bind the registry to | ||
11 | REGISTRY_PORT=5000 | ||
12 | |||
13 | # Number of workers to handle the connections | ||
14 | GUNICORN_WORKERS=4 | ||
15 | |||
16 | STANDALONE=true | ||
17 | |||
18 | MIRROR_SOURCE=https://registry-1.docker.io | ||
19 | MIRROR_SOURCE_INDEX=https://index.docker.io | ||
diff --git a/recipes-containers/docker-registry/files/docker-registry.service b/recipes-containers/docker-registry/files/docker-registry.service new file mode 100644 index 00000000..4f4cfe70 --- /dev/null +++ b/recipes-containers/docker-registry/files/docker-registry.service | |||
@@ -0,0 +1,15 @@ | |||
1 | [Unit] | ||
2 | Description=Registry server for Docker | ||
3 | After=docker.service | ||
4 | Requires=docker.service | ||
5 | |||
6 | [Service] | ||
7 | Type=simple | ||
8 | Environment=DOCKER_REGISTRY_CONFIG=/etc/docker-registry.yml | ||
9 | EnvironmentFile=-/etc/default/docker-registry | ||
10 | WorkingDirectory=#WORKDIR# | ||
11 | ExecStart=/usr/bin/gunicorn --access-logfile /var/log/docker-registry-access.log --error-logfile /var/log/docker-registry-error.log --debug --max-requests 100 --graceful-timeout 3600 -t 3600 -k gevent -b ${REGISTRY_ADDRESS}:${REGISTRY_PORT} -w ${GUNICORN_WORKERS} docker_registry.wsgi:application | ||
12 | Restart=on-failure | ||
13 | |||
14 | [Install] | ||
15 | WantedBy=multi-user.target | ||