diff --git a/docker-registry-auth/hooks/init b/docker-registry-auth/hooks/init new file mode 100755 index 0000000..656ba14 --- /dev/null +++ b/docker-registry-auth/hooks/init @@ -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 < "$SERVICE_CONFIGSTORE/etc/docker-auth/realm" \ No newline at end of file diff --git a/docker-registry-auth/hooks/pre_deploy b/docker-registry-auth/hooks/pre_deploy new file mode 100755 index 0000000..6f4bd36 --- /dev/null +++ b/docker-registry-auth/hooks/pre_deploy @@ -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 diff --git a/docker-registry-auth/hooks/registry_auth-relation-joined b/docker-registry-auth/hooks/registry_auth-relation-joined new file mode 100755 index 0000000..f288c71 --- /dev/null +++ b/docker-registry-auth/hooks/registry_auth-relation-joined @@ -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 < $SERVICE_CONFIGSTORE/etc/docker-auth/realm \ No newline at end of file diff --git a/docker-registry-auth/lib/common b/docker-registry-auth/lib/common new file mode 100644 index 0000000..90dc3c0 --- /dev/null +++ b/docker-registry-auth/lib/common @@ -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 +" +} diff --git a/docker-registry-auth/metadata.yaml b/docker-registry-auth/metadata.yaml new file mode 100644 index 0000000..509de9e --- /dev/null +++ b/docker-registry-auth/metadata.yaml @@ -0,0 +1,30 @@ +summary: "Authentication for docker Registry" +maintainer: "Valentin Lab " +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" diff --git a/precise/docker-registry/src/etc/default/docker-registry b/docker-registry-auth/src/etc/default/docker-registry similarity index 100% rename from precise/docker-registry/src/etc/default/docker-registry rename to docker-registry-auth/src/etc/default/docker-registry diff --git a/precise/docker-registry/src/etc/init.d/docker-registry b/docker-registry-auth/src/etc/init.d/docker-registry similarity index 100% rename from precise/docker-registry/src/etc/init.d/docker-registry rename to docker-registry-auth/src/etc/init.d/docker-registry diff --git a/docker-registry/hooks/init b/docker-registry/hooks/init new file mode 100755 index 0000000..3711af3 --- /dev/null +++ b/docker-registry/hooks/init @@ -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 < "$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 +" +} diff --git a/docker-registry/metadata.yaml b/docker-registry/metadata.yaml new file mode 100644 index 0000000..e88a5fd --- /dev/null +++ b/docker-registry/metadata.yaml @@ -0,0 +1,95 @@ +summary: "Docker Registry" +maintainer: "Valentin Lab " +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: + # 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" diff --git a/precise/docker-registry/metadata.yaml b/precise/docker-registry/metadata.yaml deleted file mode 100644 index 0406be7..0000000 --- a/precise/docker-registry/metadata.yaml +++ /dev/null @@ -1,8 +0,0 @@ -name: docker-registry -summary: "Docker Registry" -maintainer: "Valentin Lab " -inherit: base-0k -description: | - Docker Registry -data-resources: - - /var/lib/docker-registry