Valentin Lab
6 years ago
16 changed files with 496 additions and 8 deletions
-
72docker-registry-auth/hooks/init
-
20docker-registry-auth/hooks/pre_deploy
-
50docker-registry-auth/hooks/registry_auth-relation-joined
-
12docker-registry-auth/hooks/web_proxy-relation-joined
-
55docker-registry-auth/lib/common
-
30docker-registry-auth/metadata.yaml
-
0docker-registry-auth/src/etc/default/docker-registry
-
0docker-registry-auth/src/etc/init.d/docker-registry
-
80docker-registry/hooks/init
-
0docker-registry/hooks/install
-
8docker-registry/hooks/pre_deploy
-
13docker-registry/hooks/registry_auth-relation-joined
-
22docker-registry/hooks/web_proxy-relation-joined
-
39docker-registry/lib/common
-
95docker-registry/metadata.yaml
-
8precise/docker-registry/metadata.yaml
@ -0,0 +1,72 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
## Init is run on host |
||||
|
## For now it is run every time the script is launched, but |
||||
|
## it should be launched only once after build. |
||||
|
|
||||
|
## Accessible variables are: |
||||
|
## - SERVICE_NAME Name of current service |
||||
|
## - DOCKER_BASE_IMAGE Base image from which this service might be built if any |
||||
|
## - SERVICE_DATASTORE Location on host of the DATASTORE of this service |
||||
|
## - SERVICE_CONFIGSTORE Location on host of the CONFIGSTORE of this service |
||||
|
|
||||
|
|
||||
|
. lib/common |
||||
|
|
||||
|
set -e |
||||
|
|
||||
|
if [ -e "$HOST_CONFIG_FILE" ]; then |
||||
|
echo > "$HOST_CONFIG_FILE" |
||||
|
else |
||||
|
mkdir -p "$(dirname "$HOST_CONFIG_FILE")" |
||||
|
touch "$HOST_CONFIG_FILE" |
||||
|
fi |
||||
|
|
||||
|
init-config-add " |
||||
|
$SERVICE_NAME: |
||||
|
volumes: |
||||
|
- $HOST_CONFIG_FILE:$CONFIG_FILE |
||||
|
" |
||||
|
|
||||
|
|
||||
|
## |
||||
|
## Merge compose options |
||||
|
## |
||||
|
|
||||
|
service_def=$(get_compose_service_def "$SERVICE_NAME") || return 1 |
||||
|
options=$(e "$service_def" | shyaml -y get-value "options") || true |
||||
|
|
||||
|
if [ "$options" ]; then |
||||
|
while read-0 key value; do |
||||
|
case "$key" in |
||||
|
users) |
||||
|
user_conf=$(make_users_config "$value") || exit 1 |
||||
|
e "$user_conf" | ini_merge |
||||
|
;; |
||||
|
acl) |
||||
|
yaml_key_val_str "$key" "$value" | ini_merge |
||||
|
;; |
||||
|
*) |
||||
|
err "Unknown key '$key' in options." |
||||
|
exit 1 |
||||
|
;; |
||||
|
esac |
||||
|
done < <(e "$options" | shyaml key-values-0) |
||||
|
fi |
||||
|
|
||||
|
|
||||
|
## XXXvlab: ports should be not repeated (is repeated in charm metadata, or docker image) |
||||
|
ini_merge <<EOF |
||||
|
server: |
||||
|
addr: ":5001" |
||||
|
EOF |
||||
|
|
||||
|
|
||||
|
ini_merge <<EOF |
||||
|
token: |
||||
|
issuer: "Acme auth server" |
||||
|
expiration: 900 |
||||
|
EOF |
||||
|
|
||||
|
## Can be modified by web-proxy relation |
||||
|
echo "http://$SERVICE_NAME:5001" > "$SERVICE_CONFIGSTORE/etc/docker-auth/realm" |
@ -0,0 +1,20 @@ |
|||||
|
#!/bin/bash |
||||
|
## Should be executable N time in a row with same result. |
||||
|
|
||||
|
set -e |
||||
|
|
||||
|
. lib/common |
||||
|
|
||||
|
|
||||
|
if [[ $(cat "$HOST_CONFIG_FILE" | shyaml keys) != *"_auth "* ]] && |
||||
|
! cat "$HOST_CONFIG_FILE" | shyaml get-value users >/dev/null; then |
||||
|
err "No *_auth configured and no users list provided." |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if ! cat "$HOST_CONFIG_FILE" | shyaml get-value acl; then |
||||
|
err "No acl configured." |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
registry_config_hash || exit 1 |
@ -0,0 +1,50 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -e |
||||
|
|
||||
|
. lib/common |
||||
|
|
||||
|
LOCAL_CERTS_PATH=/etc/docker-auth/certs |
||||
|
|
||||
|
certs_path="$SERVICE_CONFIGSTORE$LOCAL_CERTS_PATH" |
||||
|
|
||||
|
mkdir -p "$certs_path" |
||||
|
|
||||
|
( |
||||
|
cd "$certs_path" |
||||
|
openssl req -x509 -newkey rsa:2048 -new -nodes \ |
||||
|
-keyout privkey.pem -out fullchain.pem \ |
||||
|
-subj "/C=FR/ST=Paris/L=Paris/O=ACME/OU=IT Department/CN=[domain.tld]" |
||||
|
chmod 600 privkey.pem |
||||
|
) |
||||
|
|
||||
|
cat <<EOF | ini_merge |
||||
|
|
||||
|
token: |
||||
|
certificate: "$LOCAL_CERTS_PATH/fullchain.pem" |
||||
|
key: "$LOCAL_CERTS_PATH/privkey.pem" |
||||
|
|
||||
|
EOF |
||||
|
|
||||
|
|
||||
|
config-add "\ |
||||
|
services: |
||||
|
$TARGET_SERVICE_NAME: |
||||
|
volumes: |
||||
|
- \"$certs_path:$LOCAL_CERTS_PATH:ro\" |
||||
|
$BASE_SERVICE_NAME: |
||||
|
volumes: |
||||
|
- \"$certs_path:$LOCAL_CERTS_PATH:ro\" |
||||
|
" |
||||
|
|
||||
|
|
||||
|
realm=$(cat "$SERVICE_CONFIGSTORE/etc/docker-auth/realm") || exit 1 |
||||
|
|
||||
|
relation-set registry-config "\ |
||||
|
token: |
||||
|
realm: \"$realm/auth\" |
||||
|
service: \"Docker registry\" |
||||
|
issuer: \"Acme auth server\" |
||||
|
autoredirect: false |
||||
|
rootcertbundle: \"$LOCAL_CERTS_PATH/fullchain.pem\" |
||||
|
" |
@ -0,0 +1,12 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -e |
||||
|
|
||||
|
. lib/common |
||||
|
|
||||
|
DOMAIN=$(relation-get domain) || exit 1 |
||||
|
PROTO=$(relation-get protocol) || true |
||||
|
PROTO=${PROTO:-https} |
||||
|
|
||||
|
|
||||
|
echo "$PROTO://$DOMAIN" > $SERVICE_CONFIGSTORE/etc/docker-auth/realm |
@ -0,0 +1,55 @@ |
|||||
|
# -*- mode: shell-script -*- |
||||
|
|
||||
|
CONFIG_FILE=/etc/docker-auth/config.yml |
||||
|
HOST_CONFIG_FILE="$SERVICE_CONFIGSTORE$CONFIG_FILE" |
||||
|
|
||||
|
ini_merge_str() { |
||||
|
local cfg="$1" \ |
||||
|
cache_file="$CACHEDIR/$FUNCNAME.cache.$(p0 "$@" "$(cat "$HOST_CONFIG_FILE")" | md5_compat)" \ |
||||
|
result |
||||
|
if [ -z "$cfg" ]; then |
||||
|
return 0 |
||||
|
fi |
||||
|
if [ -e "$cache_file" ]; then |
||||
|
#debug "$FUNCNAME: SESSION cache hit $1" |
||||
|
cat "$cache_file" || return 1 |
||||
|
return 0 |
||||
|
fi |
||||
|
|
||||
|
result="$(merge_yaml_str "$(cat "$HOST_CONFIG_FILE")" "$cfg")" || return 1 |
||||
|
e "$result" | tee "$cache_file" || return 1 |
||||
|
} |
||||
|
|
||||
|
|
||||
|
ini_merge() { |
||||
|
local result |
||||
|
result=$(ini_merge_str "$(cat -)") |
||||
|
e "$result" > "$HOST_CONFIG_FILE" |
||||
|
} |
||||
|
|
||||
|
|
||||
|
make_users_config() { |
||||
|
local users_charm_cfg="$1" |
||||
|
|
||||
|
echo "users:" |
||||
|
while read-0 user config; do |
||||
|
echo " \"$user\":" |
||||
|
password="$config" |
||||
|
##$(e "$config" | shyaml get-value password) || return 1 |
||||
|
bcrypt=$(e "$password" | htpasswd -niB "$user" | cut -f 2 -d ":") |
||||
|
echo " password: \"$bcrypt\"" |
||||
|
done < <(e "$users_charm_cfg" | shyaml key-values-0) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
registry_config_hash() { |
||||
|
debug "Adding config hash to enable recreating upon config change." |
||||
|
config_hash=$(cat "$HOST_CONFIG_FILE" | md5_compat) || exit 1 |
||||
|
init-config-add " |
||||
|
$MASTER_BASE_SERVICE_NAME: |
||||
|
labels: |
||||
|
- compose.config_hash=$config_hash |
||||
|
" |
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
summary: "Authentication for docker Registry" |
||||
|
maintainer: "Valentin Lab <valentin.lab@kalysto.org>" |
||||
|
docker-image: docker.0k.io/docker-registry-auth:1.3.1 |
||||
|
data-resources: |
||||
|
- /var/log/docker-auth |
||||
|
config-resources: |
||||
|
- /etc/docker-auth/ |
||||
|
|
||||
|
docker-compose: |
||||
|
command: /etc/docker-auth/config.yml |
||||
|
provides: |
||||
|
registry-auth: |
||||
|
|
||||
|
default-options: |
||||
|
# users: |
||||
|
# mylogin: mypasswd |
||||
|
# acl: |
||||
|
# - match: {account: "admin"} |
||||
|
# actions: ["*"] |
||||
|
# comment: "Admin has full access to everything." |
||||
|
# - match: {account: "user"} |
||||
|
# actions: ["pull"] |
||||
|
# comment: "User \"user\" can pull stuff." |
||||
|
|
||||
|
uses: |
||||
|
web-proxy: |
||||
|
#constraint: required | recommended | optional |
||||
|
constraint: recommended |
||||
|
solves: |
||||
|
proxy: "Public access" |
@ -0,0 +1,80 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
## Init is run on host |
||||
|
## For now it is run every time the script is launched, but |
||||
|
## it should be launched only once after build. |
||||
|
|
||||
|
## Accessible variables are: |
||||
|
## - SERVICE_NAME Name of current service |
||||
|
## - DOCKER_BASE_IMAGE Base image from which this service might be built if any |
||||
|
## - SERVICE_DATASTORE Location on host of the DATASTORE of this service |
||||
|
## - SERVICE_CONFIGSTORE Location on host of the CONFIGSTORE of this service |
||||
|
|
||||
|
|
||||
|
. lib/common |
||||
|
|
||||
|
set -e |
||||
|
|
||||
|
if [ -e "$HOST_CONFIG_FILE" ]; then |
||||
|
echo > "$HOST_CONFIG_FILE" |
||||
|
else |
||||
|
mkdir -p "$(dirname "$HOST_CONFIG_FILE")" |
||||
|
touch "$HOST_CONFIG_FILE" |
||||
|
fi |
||||
|
|
||||
|
init-config-add " |
||||
|
$SERVICE_NAME: |
||||
|
volumes: |
||||
|
- $HOST_CONFIG_FILE:$CONFIG_FILE |
||||
|
" |
||||
|
|
||||
|
ini_merge <<EOF || exit 1 |
||||
|
version: 0.1 |
||||
|
storage: |
||||
|
filesystem: |
||||
|
rootdirectory: /var/lib/docker-registry |
||||
|
|
||||
|
http: |
||||
|
addr: $SERVICE_NAME:5000 |
||||
|
net: tcp |
||||
|
host: http://$SERVICE_NAME:5000 |
||||
|
## XXXvlab: not used for now |
||||
|
#secret: asecretforlocaldevelopment |
||||
|
relativeurls: false |
||||
|
# debug: |
||||
|
# addr: localhost:5001 |
||||
|
# headers: |
||||
|
# X-Content-Type-Options: [nosniff] |
||||
|
# http2: |
||||
|
# disabled: false |
||||
|
|
||||
|
EOF |
||||
|
|
||||
|
|
||||
|
## |
||||
|
## Merge compose options |
||||
|
## |
||||
|
|
||||
|
service_def=$(get_compose_service_def "$SERVICE_NAME") || return 1 |
||||
|
options=$(e "$service_def" | shyaml -y get-value "options") || true |
||||
|
|
||||
|
if [ "$options" ]; then |
||||
|
while read-0 key value; do |
||||
|
case "$key" in |
||||
|
auth|storage|middleware|reporting|http|redis|version) |
||||
|
err "You should not configure '$key' in this charm." |
||||
|
exit 1 |
||||
|
;; |
||||
|
log|loglevel|notifications|health|proxy|compatibility|validation) |
||||
|
continue |
||||
|
;; |
||||
|
*) |
||||
|
err "Unknown key '$key' in options." |
||||
|
exit 1 |
||||
|
;; |
||||
|
esac |
||||
|
done < <(e "$options" | shyaml key-values-0) |
||||
|
|
||||
|
e "$options" | ini_merge || exit 1 |
||||
|
|
||||
|
fi |
@ -0,0 +1,8 @@ |
|||||
|
#!/bin/bash |
||||
|
## Should be executable N time in a row with same result. |
||||
|
|
||||
|
set -e |
||||
|
|
||||
|
. lib/common |
||||
|
|
||||
|
registry_config_hash || exit 1 |
@ -0,0 +1,13 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -e |
||||
|
|
||||
|
. lib/common |
||||
|
|
||||
|
cfg=$(relation-get registry-config) || { |
||||
|
err "registry-auth $TARGET_SERVICE_NAME is expected to set 'registry-config'" |
||||
|
exit 1 |
||||
|
} |
||||
|
|
||||
|
yaml_key_val_str "auth" "$cfg" | ini_merge |
||||
|
|
@ -0,0 +1,22 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -e |
||||
|
|
||||
|
. lib/common |
||||
|
|
||||
|
DOMAIN=$(relation-get domain) || exit 1 |
||||
|
PROTO=$(relation-get protocol) || true |
||||
|
PROTO=${PROTO:-https} |
||||
|
|
||||
|
## These are mainly to setup the correct web-hook |
||||
|
if [ "$MASTER_BASE_SERVICE_NAME" == "$DOMAIN" ]; then |
||||
|
## This is because the IP will be the docker container version |
||||
|
PROTO=http |
||||
|
fi |
||||
|
|
||||
|
ini_merge <<EOF |
||||
|
|
||||
|
http: |
||||
|
host: $PROTO://$DOMAIN |
||||
|
|
||||
|
EOF |
@ -0,0 +1,39 @@ |
|||||
|
# -*- mode: shell-script -*- |
||||
|
|
||||
|
CONFIG_FILE=/etc/docker/registry/config.yml |
||||
|
HOST_CONFIG_FILE="$SERVICE_CONFIGSTORE$CONFIG_FILE" |
||||
|
|
||||
|
ini_merge_str() { |
||||
|
local cfg="$1" \ |
||||
|
cache_file="$CACHEDIR/$FUNCNAME.cache.$(p0 "$@" "$(cat "$HOST_CONFIG_FILE")" | md5_compat)" \ |
||||
|
result |
||||
|
if [ -z "$cfg" ]; then |
||||
|
return 0 |
||||
|
fi |
||||
|
if [ -e "$cache_file" ]; then |
||||
|
#debug "$FUNCNAME: SESSION cache hit $1" |
||||
|
cat "$cache_file" || return 1 |
||||
|
return 0 |
||||
|
fi |
||||
|
|
||||
|
result="$(merge_yaml_str "$(cat "$HOST_CONFIG_FILE")" "$cfg")" || return 1 |
||||
|
e "$result" | tee "$cache_file" || return 1 |
||||
|
} |
||||
|
|
||||
|
|
||||
|
ini_merge() { |
||||
|
local result |
||||
|
result=$(ini_merge_str "$(cat -)") |
||||
|
e "$result" > "$HOST_CONFIG_FILE" |
||||
|
} |
||||
|
|
||||
|
|
||||
|
registry_config_hash() { |
||||
|
debug "Adding config hash to enable recreating upon config change." |
||||
|
config_hash=$(cat "$HOST_CONFIG_FILE" | md5_compat) || exit 1 |
||||
|
init-config-add " |
||||
|
$MASTER_BASE_SERVICE_NAME: |
||||
|
labels: |
||||
|
- compose.config_hash=$config_hash |
||||
|
" |
||||
|
} |
@ -0,0 +1,95 @@ |
|||||
|
summary: "Docker Registry" |
||||
|
maintainer: "Valentin Lab <valentin.lab@kalysto.org>" |
||||
|
inherit: base-0k |
||||
|
description: | |
||||
|
Docker Registry |
||||
|
|
||||
|
docker-image: docker.0k.io/registry:2.0 |
||||
|
data-resources: |
||||
|
- /var/lib/docker-registry |
||||
|
|
||||
|
default-options: |
||||
|
# log: |
||||
|
# accesslog: |
||||
|
# disabled: true |
||||
|
# level: debug |
||||
|
# formatter: text |
||||
|
# fields: |
||||
|
# service: registry |
||||
|
# environment: staging |
||||
|
# hooks: |
||||
|
# - type: mail |
||||
|
# disabled: true |
||||
|
# levels: |
||||
|
# - panic |
||||
|
# options: |
||||
|
# smtp: |
||||
|
# addr: mail.example.com:25 |
||||
|
# username: mailuser |
||||
|
# password: password |
||||
|
# insecure: true |
||||
|
# from: sender@example.com |
||||
|
# to: |
||||
|
# - errors@example.com |
||||
|
# notifications: |
||||
|
# endpoints: |
||||
|
# - name: alistener |
||||
|
# disabled: false |
||||
|
# url: https://my.listener.com/event |
||||
|
# headers: <http.Header> |
||||
|
# timeout: 500 |
||||
|
# threshold: 5 |
||||
|
# backoff: 1000 |
||||
|
# ignoredmediatypes: |
||||
|
# - application/octet-stream |
||||
|
|
||||
|
# health: |
||||
|
# storagedriver: |
||||
|
# enabled: true |
||||
|
# interval: 10s |
||||
|
# threshold: 3 |
||||
|
# file: |
||||
|
# - file: /path/to/checked/file |
||||
|
# interval: 10s |
||||
|
# http: |
||||
|
# - uri: http://server.to.check/must/return/200 |
||||
|
# headers: |
||||
|
# Authorization: [Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==] |
||||
|
# statuscode: 200 |
||||
|
# timeout: 3s |
||||
|
# interval: 10s |
||||
|
# threshold: 3 |
||||
|
# tcp: |
||||
|
# - addr: redis-server.domain.com:6379 |
||||
|
# timeout: 3s |
||||
|
# interval: 10s |
||||
|
# threshold: 3 |
||||
|
|
||||
|
# proxy: |
||||
|
# remoteurl: https://registry-1.docker.io |
||||
|
# username: [username] |
||||
|
# password: [password] |
||||
|
# compatibility: |
||||
|
# schema1: |
||||
|
# signingkeyfile: /etc/registry/key.json |
||||
|
# validation: |
||||
|
# enabled: true |
||||
|
# manifests: |
||||
|
# urls: |
||||
|
# allow: |
||||
|
# - ^https?://([^/]+\.)*example\.com/ |
||||
|
# deny: |
||||
|
# - ^https?://www\.example\.com/ |
||||
|
|
||||
|
uses: |
||||
|
registry-auth: |
||||
|
#constraint: required | recommended | optional |
||||
|
constraint: recommended |
||||
|
solves: |
||||
|
unmanaged-auth: "Authentication is not managed" |
||||
|
|
||||
|
web-proxy: |
||||
|
#constraint: required | recommended | optional |
||||
|
constraint: recommended |
||||
|
solves: |
||||
|
proxy: "Public access" |
@ -1,8 +0,0 @@ |
|||||
name: docker-registry |
|
||||
summary: "Docker Registry" |
|
||||
maintainer: "Valentin Lab <valentin.lab@kalysto.org>" |
|
||||
inherit: base-0k |
|
||||
description: | |
|
||||
Docker Registry |
|
||||
data-resources: |
|
||||
- /var/lib/docker-registry |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue