Skip to content

Commit

Permalink
feat(registry): Configurable storage backends
Browse files Browse the repository at this point in the history
Refactored the deis-registry configuration template to
make the storage backend configurable via etcd

Fixes deis#1119

Also start deis-cache before starting deis-registry and grant
deis-registry access to the /deis/cache etcd key space

Fixes deis#1120
  • Loading branch information
johanneswuerbach committed Jul 25, 2014
1 parent 26e4d96 commit 45fb9a6
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 81 deletions.
18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ endef
# TODO: re-evaluate the fragile start order
COMPONENTS=builder cache controller database logger registry
ALL_COMPONENTS=$(COMPONENTS) router
START_COMPONENTS=registry logger cache database
START_COMPONENTS=logger cache database

ALL_UNITS = $(foreach C,$(COMPONENTS),$(wildcard $(C)/systemd/*.service))
START_UNITS = $(foreach C,$(START_COMPONENTS),$(wildcard $(C)/systemd/*.service))
Expand All @@ -42,6 +42,7 @@ full-clean: clean

install: check-fleet install-routers install-data-containers
$(FLEETCTL) load $(START_UNITS)
$(FLEETCTL) load registry/systemd/*.service
$(FLEETCTL) load controller/systemd/*.service
$(FLEETCTL) load builder/systemd/*.service

Expand Down Expand Up @@ -83,9 +84,20 @@ rsync:
run: install start

start: check-fleet start-warning start-routers
@# registry logger cache database
$(call echo_yellow,"Waiting for deis-registry to start...")
@# logger cache database
$(call echo_yellow,"Waiting for deis-cache to start...")
$(FLEETCTL) start -no-block $(START_UNITS)
@until $(FLEETCTL) list-units | egrep -q "deis-cache\..+(running|failed)"; \
do sleep 2; \
printf "\033[0;33mStatus:\033[0m "; $(FLEETCTL) list-units | \
grep "deis-cache\." | awk '{printf "%-10s (%s) \r", $$4, $$5}'; \
sleep 8; \
done
$(call check_for_errors)

@# registry
$(call echo_yellow,"Waiting for deis-registry to start...")
$(FLEETCTL) start -no-block registry/systemd/*
@until $(FLEETCTL) list-units | egrep -q "deis-registry\..+(running|failed)"; \
do sleep 2; \
printf "\033[0;33mStatus:\033[0m "; $(FLEETCTL) list-units | \
Expand Down
2 changes: 1 addition & 1 deletion registry/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ RUN pip install /docker-registry/depends/docker-registry-core
RUN pip install file:///docker-registry#egg=docker-registry[bugsnag]

ENV DOCKER_REGISTRY_CONFIG /docker-registry/config/config.yml
ENV SETTINGS_FLAVOR dev
ENV SETTINGS_FLAVOR deis

# create data volume
RUN mkdir -p /data/repositories && chown -R registry:registry /data
Expand Down
3 changes: 2 additions & 1 deletion registry/conf.d/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ uid = 0
gid = 0
mode = "0644"
keys = [
"/deis/registry",
"/deis/cache",
"/deis/registry"
]
check_cmd = "/app/bin/check {{ .src }}"
reload_cmd = "/app/bin/reload"
186 changes: 110 additions & 76 deletions registry/templates/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# The `common' part is automatically included (and possibly overriden by all
# other flavors)
# All other flavors inherit the `common' config snippet
common: &common
# Default log level is info
loglevel: _env:LOGLEVEL:info
Expand All @@ -24,11 +23,11 @@ common: &common
source_index: _env:MIRROR_SOURCE_INDEX # https://index.docker.io
tags_cache_ttl: _env:MIRROR_TAGS_CACHE_TTL:172800 # seconds

# cache:
# host: _env:CACHE_REDIS_HOST:localhost
# port: _env:CACHE_REDIS_PORT:6379
# db: 0
# password: _env:CACHE_REDIS_PASSWORD
cache:
host: {{ or (.deis_cache_host) "" }}
port: {{ or (.deis_cache_port) "" }}
password: _env:CACHE_REDIS_PASSWORD
db: 1

# Enabling LRU cache for small files
# This speeds up read/write on small files
Expand All @@ -40,95 +39,130 @@ common: &common
# password: _env:CACHE_LRU_REDIS_PASSWORD

# Enabling these options makes the Registry send an email on each code Exception
{{ if .deis_registry_smtpHost }}
email_exceptions:
smtp_host: _env:SMTP_HOST
smtp_port: _env:SMTP_PORT:25
smtp_login: _env:SMTP_LOGIN
smtp_password: _env:SMTP_PASSWORD
smtp_secure: _env:SMTP_SECURE:false
from_addr: _env:SMTP_FROM_ADDR:[email protected]
to_addr: _env:SMTP_TO_ADDR:[email protected]
smtp_host: {{ or (.deis_registry_smtpHost) "" }}
smtp_port: {{ or (.deis_registry_smtpPort) "25" }}
smtp_login: {{ or (.deis_registry_smtpLogin) "" }}
smtp_password: {{ or (.deis_registry_smtpPassword) "" }}
smtp_secure: bool({{ or (.deis_registry_smtpSecure) "false" }})
from_addr: {{ or (.deis_registry_smtpFrom) "[email protected]" }}
to_addr: {{ or (.deis_registry_smtpTo) "[email protected]" }}
{{ end }}

# Enable bugsnag (set the API key)
bugsnag: _env:BUGSNAG

# This is the default configuration when no flavor is specified
dev:
local: &local
<<: *common
storage: local
storage_path: /data

{{ if .deis_registry_s3accessKey }}
# To specify another flavor, set the environment variable SETTINGS_FLAVOR
# $ export SETTINGS_FLAVOR=prod
prod:

s3: &s3
<<: *common
storage: s3
storage_path: /data
# Amazon S3 Storage Configuration
s3_access_key: {{ .deis_registry_s3accessKey }}
s3_secret_key: {{ .deis_registry_s3secretKey }}
s3_region: {{ .deis_registry_s3region }}
s3_bucket: {{ .deis_registry_s3bucket }}
boto_bucket: {{ .deis_registry_s3bucket }}
s3_encrypt: bool({{ .deis_registry_s3encrypt }})
s3_secure: bool({{ .deis_registry_s3secure }})
storage_redirect: True
# Enabling query cache on Redis
cache:
host: {{ .deis_cache_host }}
port: {{ .deis_cache_port }}
db: 1
# Enabling these options makes the Registry send an email on each code Exception
email_exceptions:
smtp_host: {{ .deis_registry_smtpHost }}
smtp_port: {{ .deis_registry_smtpPort }}
smtp_login: {{ .deis_registry_smtpLogin }}
smtp_password: {{ .deis_registry_smtpPassword }}
smtp_secure: {{ .deis_registry_smtpSecure }}
from_addr: {{ .deis_registry_smtpFrom }}
to_addr: {{ .deis_registry_smtpTo }}
# Enable bugsnag (set the API key)
bugsnag: REPLACEME
{{ end }}
s3_region: {{ or (.deis_registry_s3region) "" }}
s3_bucket: {{ or (.deis_registry_s3bucket) "" }}
boto_bucket: {{ or (.deis_registry_s3bucket) "" }}
storage_path: {{ or (.deis_registry_s3path) "/registry" }}
s3_encrypt: bool({{ or (.deis_registry_s3encrypt) "true" }})
s3_secure: bool({{ or (.deis_registry_s3secure) "true" }})
s3_access_key: {{ or (.deis_registry_s3accessKey) "" }}
s3_secret_key: {{ or (.deis_registry_s3secretKey) "" }}

# This flavor is automatically used by unit tests
test:
storage: local
storage_path: /tmp/test
# Google Cloud Storage Configuration
# See:
# https://developers.google.com/storage/docs/reference/v1/getting-startedv1#keys
# for details on access and secret keys.
gcs:
<<: *common
storage: gcs
boto_bucket: _env:GCS_BUCKET
storage_path: _env:STORAGE_PATH:/registry
gs_secure: _env:GCS_SECURE:true
gs_access_key: _env:GCS_KEY
gs_secret_key: _env:GCS_SECRET
# OAuth 2.0 authentication with the storage.
# oauth2 can be set to true or false. If it is set to true, gs_access_key,
# gs_secret_key and gs_secure are not needed.
# Client ID and Client Secret must be set into OAUTH2_CLIENT_ID and
# OAUTH2_CLIENT_SECRET environment variables.
# See: https://developers.google.com/accounts/docs/OAuth2.
oauth2: _env:GCS_OAUTH2:false

# This flavor is for storing images in Openstack Swift
{{ if .deis_registry_swiftAuthURL }}
swift:
swift: &swift
<<: *common
storage: swift
storage_path: "_env:STORAGE_PATH:/registry"
swift_authurl: {{ .deis_registry_swiftAuthURL }}
swift_container: {{ .deis_registry_swiftContainer }}
swift_user: {{ .deis_registry_swiftUser }}
swift_password: {{ .deis_registry_swiftPassword }}
swift_tenant_name: {{ .deis_registry_swiftTenantName }}
swift_region_name: {{ .deis_registry_swiftRegionName }}
{{ end }}
storage_path: _env:STORAGE_PATH:/registry
# keystone authorization
swift_authurl: {{ or (.deis_registry_swiftAuthURL) "" }}
swift_container: {{ or (.deis_registry_swiftContainer) "" }}
swift_user: {{ or (.deis_registry_swiftUser) "" }}
swift_password: {{ or (.deis_registry_swiftPassword) "" }}
swift_tenant_name: {{ or (.deis_registry_swiftTenantName) "" }}
swift_region_name: {{ or (.deis_registry_swiftRegionName) "" }}

# This flavor stores the images in Glance (to integrate with openstack)
# See also: https://github.com/dotcloud/openstack-docker
openstack:
glance: &glance
<<: *common
storage: glance
storage_alternate: local
storage_path: /tmp/registry
loglevel: debug
storage_alternate: _env:GLANCE_STORAGE_ALTERNATE:file
storage_path: _env:STORAGE_PATH:/tmp/registry

openstack:
<<: *glance

# This flavor stores the images in Glance (to integrate with openstack)
# and tags in Swift.
{{ if .deis_registry_swiftAuthURL }}
openstack-swift:
glance-swift: &glance-swift
<<: *swift
storage: glance
storage_path: /registry
storage_alternate: swift
# keystone authorization
swift_authurl: {{ .deis_registry_swiftAuthURL }}
swift_container: {{ .deis_registry_swiftContainer }}
swift_user: {{ .deis_registry_swiftUser }}
swift_password: {{ .deis_registry_swiftPassword }}
swift_tenant_name: {{ .deis_registry_swiftTenantName }}
swift_region_name: {{ .deis_registry_swiftRegionName }}
{{ end }}

openstack-swift:
<<: *glance-swift

elliptics:
<<: *common
storage: elliptics
elliptics_nodes: _env:ELLIPTICS_NODES
elliptics_wait_timeout: _env:ELLIPTICS_WAIT_TIMEOUT:60
elliptics_check_timeout: _env:ELLIPTICS_CHECK_TIMEOUT:60
elliptics_io_thread_num: _env:ELLIPTICS_IO_THREAD_NUM:2
elliptics_net_thread_num: _env:ELLIPTICS_NET_THREAD_NUM:2
elliptics_nonblocking_io_thread_num: _env:ELLIPTICS_NONBLOCKING_IO_THREAD_NUM:2
elliptics_groups: _env:ELLIPTICS_GROUPS
elliptics_verbosity: _env:ELLIPTICS_VERBOSITY:4
elliptics_logfile: _env:ELLIPTICS_LOGFILE:/dev/stderr
elliptics_addr_family: _env:ELLIPTICS_ADDR_FAMILY:2



# This is the default configuration when no flavor is specified
dev: &dev
<<: *local
loglevel: _env:LOGLEVEL:debug
search_backend: _env:SEARCH_BACKEND:sqlalchemy

# This flavor is used by unit tests
test:
<<: *dev
index_endpoint: https://indexstaging-docker.dotcloud.com
standalone: true
storage_path: _env:STORAGE_PATH:./tmp/test

# To specify another flavor, set the environment variable SETTINGS_FLAVOR
# $ export SETTINGS_FLAVOR=prod
prod:
<<: *s3
storage_path: _env:STORAGE_PATH:/prod

# Flavor used by deis
deis:
{{ if .deis_registry_s3accessKey }}<<: *s3
{{ else if .deis_registry_swiftAuthURL }} <<: *openstack-swift
{{ else }} <<: *local
{{ end }}
10 changes: 10 additions & 0 deletions registry/tests/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/deis/deis/tests/dockercliutils"
"github.com/deis/deis/tests/etcdutils"
"github.com/deis/deis/tests/utils"
)

Expand Down Expand Up @@ -32,13 +33,22 @@ func runDeisRegistryTest(
}

func TestRegistry(t *testing.T) {
setkeys := []string{
"/deis/cache/host",
"/deis/cache/port",
}
setdir := []string{
"/deis/cache",
}
testID := utils.NewUuid()
err := dockercliutils.BuildImage(t, "../", "deis/registry:"+testID)
if err != nil {
t.Fatal(err)
}
etcdPort := utils.GetRandomPort()
dockercliutils.RunEtcdTest(t, testID, etcdPort)
handler := etcdutils.InitetcdValues(setdir, setkeys, etcdPort)
etcdutils.Publishvalues(t, handler)
servicePort := utils.GetRandomPort()
fmt.Printf("--- Test deis-registry-%s at port %s\n", testID, servicePort)
runDeisRegistryTest(t, testID, etcdPort, servicePort)
Expand Down

0 comments on commit 45fb9a6

Please sign in to comment.