diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f50999f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.twgit_features_subject +/.twgit diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f6e56b9 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project follows MariaDB versioning. + +## 10.2.14 - 2018-04-13 +Initial release diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6c12ed9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Osixia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dc54b78 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +NAME = osixia/mariadb-helper +VERSION = 10.2.14 + +.PHONY: build build-nocache test tag-latest push push-latest release git-tag-version + +build: + docker build -t $(NAME):$(VERSION) --rm image + +build-nocache: + docker build -t $(NAME):$(VERSION) --no-cache --rm image + +test: + env NAME=$(NAME) VERSION=$(VERSION) bats test/test.bats + +tag-latest: + docker tag $(NAME):$(VERSION) $(NAME):latest + +push: + docker push $(NAME):$(VERSION) + +push-latest: + docker push $(NAME):latest + +release: build test tag-latest push push-latest + +git-tag-version: release + git tag -a v$(VERSION) -m "v$(VERSION)" + git push origin v$(VERSION) diff --git a/README.md b/README.md index 7a925cf..4168f96 100644 --- a/README.md +++ b/README.md @@ -1 +1,16 @@ -# mariadb-helper +# osixia/mariadb-helper + +[![Docker Pulls](https://img.shields.io/docker/pulls/osixia/mariadb-helper.svg)][hub] +[![Docker Stars](https://img.shields.io/docker/stars/osixia/mariadb-helper.svg)][hub] +[![](https://images.microbadger.com/badges/image/osixia/mariadb-helper.svg)](http://microbadger.com/images/osixia/mariadb-helper "Get your own image badge on microbadger.com") + +[hub]: https://hub.docker.com/r/osixia/mariadb-helper/ + +## Security +If you discover a security vulnerability within this docker image, please send an email to the Osixia! team at security@osixia.net. For minor vulnerabilities feel free to add an issue here on github. + +Please include as many details as possible. + +## Changelog + +Please refer to: [CHANGELOG.md](CHANGELOG.md) diff --git a/image/Dockerfile b/image/Dockerfile new file mode 100644 index 0000000..452291d --- /dev/null +++ b/image/Dockerfile @@ -0,0 +1,40 @@ +# Use osixia/light-baseimage +# sources: https://github.com/osixia/docker-light-baseimage +FROM osixia/light-baseimage:1.1.1 +MAINTAINER Bertrand Gouny + +# MariaDB version +ARG MARIADB_MAJOR=10.2 +ARG MARIADB_VERSION=10.2.14+maria~stretch + +# Add MariaDB repository +RUN apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xF1656F24C74CD1D8 \ + && echo "deb http://ftp.igh.cnrs.fr/pub/mariadb/repo/$MARIADB_MAJOR/debian stretch main" > /etc/apt/sources.list.d/mariadb.list \ + && { \ + echo 'Package: *'; \ + echo 'Pin: release o=MariaDB'; \ + echo 'Pin-Priority: 999'; \ + } > /etc/apt/preferences.d/mariadb + # add repository pinning to make sure dependencies from this MariaDB repo are preferred over Debian dependencie + +# Add multiple process stack and ssl tools +# sources: https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/add-multiple-process-stack +# https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/add-service-available +#  https://github.com/osixia/docker-light-baseimage/blob/stable/image/service-available/:ssl-tools/download.sh +# Install MariaDB and xtrabackup +RUN apt-get -y update \ + && /container/tool/add-service-available :ssl-tools \ + && LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + mariadb-client=$MARIADB_VERSION \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Add service directory to /container/service +ADD service /container/service + +# Use baseimage install-service script +# https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/install-service +RUN /container/tool/install-service + +# Add default env variables +ADD environment /container/environment/99-default diff --git a/image/environment/default.startup.yaml b/image/environment/default.startup.yaml new file mode 100644 index 0000000..c96535b --- /dev/null +++ b/image/environment/default.startup.yaml @@ -0,0 +1,39 @@ +MARIADB_HOST: mariadb + +MARIADB_FROM_DATABASE: stable +MARIADB_TO_DATABASE: example-app-hotfix-0-1-19 + +MARIADB_TO_DATABASE_GRANT_USER: admin +MARIADB_TO_DATABASE_GRANT_USER_HOST: 127.0.0.1 +MARIADB_TO_DATABASE_GRANT_PRIVILEGES: ALL + +# Prefix MARIADB_FROM_DATABASE database with MARIADB_TO_DATABASE regex capture group +# example: +# MARIADB_FROM_DATABASE: stable +# MARIADB_TO_DATABASE: example-app-hotfix-0-1-19 +# MARIADB_FROM_DATABASE_REGEX: (.*-)[feature|release|hotfix|demo].* +# +# MARIADB_FROM_DATABASE will becomes: example-app-stable +MARIADB_FROM_DATABASE_REGEX: "(.*-)[feature|release|hotfix|demo].*" + +MARIADB_ROOT_USER: admin +MARIADB_ROOT_PASSWORD: admin + +# ssl +MARIADB_SSL: true +MARIADB_SSL_CIPHER_SUITE: TLSv1.2 + +MARIADB_SSL_CRT_FILENAME: mariadb.crt +MARIADB_SSL_KEY_FILENAME: mariadb.key +MARIADB_SSL_CA_CRT_FILENAME: ca.crt + +# ssl-helper environment variables prefix +MARIADB_SSL_HELPER_PREFIX: database # ssl-helper first search config from DATABASE_SSL_HELPER_* variables, before SSL_HELPER_* variables. + +DSN_EXPORT_FILE: +DSN_EXPORT_VARIABLE_NAME: +DSN_HOST: +DSN_USER: +DSN_PASSWORD: +DSN_DATABASE: +DSN_ARGS: diff --git a/image/service/dsn-helper/startup.sh b/image/service/dsn-helper/startup.sh new file mode 100755 index 0000000..c06e86b --- /dev/null +++ b/image/service/dsn-helper/startup.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -o pipefail + +# set -x (bash debug) if log level is trace +# https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/log-helper +log-helper level eq trace && set -x + +if [ -n "${DSN_EXPORT_FILE}" ]; then + + if [ -z "${DSN_EXPORT_VARIABLE_NAME}" ]; then + log-helper error "Error: DSN_EXPORT_VARIABLE_NAME must be set" + exit 1 + fi + + mkdir -p "$(dirname "${DSN_EXPORT_FILE}")" && touch "${DSN_EXPORT_FILE}" + + DSN="${DSN_EXPORT_VARIABLE_NAME}=${DSN_USER}:${DSN_PASSWORD}@tcp(${DSN_HOST}:3306)/${DSN_DATABASE}${DSN_ARGS}" + + log-helper debug "Export ${DSN} to ${DSN_EXPORT_FILE}" + echo "${DSN}" > ${DSN_EXPORT_FILE} + log-helper info "Done." + +fi + +exit 0 diff --git a/image/service/mariadb-helper/assets/certs/README.md b/image/service/mariadb-helper/assets/certs/README.md new file mode 100644 index 0000000..9dcbeae --- /dev/null +++ b/image/service/mariadb-helper/assets/certs/README.md @@ -0,0 +1,2 @@ +Add your ssl server certificate, key and the CA certificate (if any) here +or during docker run mount a data volume with those files to /container/service/mariadb-helper/assets/certs diff --git a/image/service/mariadb-helper/startup.sh b/image/service/mariadb-helper/startup.sh new file mode 100755 index 0000000..1826289 --- /dev/null +++ b/image/service/mariadb-helper/startup.sh @@ -0,0 +1,78 @@ +#!/bin/bash +set -o pipefail + +# set -x (bash debug) if log level is trace +# https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/log-helper +log-helper level eq trace && set -x + +if [ -z "${MARIADB_HOST}" ]; then + log-helper error "Error: MARIADB_HOST must be set." + exit 0 +fi + +if [ -z "${MARIADB_FROM_DATABASE}" ] || [ -z "${MARIADB_TO_DATABASE}" ]; then + log-helper error "Error: MARIADB_FROM_DATABASE and MARIADB_TO_DATABASE must be set." + exit 0 +fi + +if [ -z "${MARIADB_ROOT_USER}" ] || [ -z "${MARIADB_ROOT_PASSWORD}" ]; then + log-helper error "Error: MARIADB_ROOT_USER and MARIADB_ROOT_PASSWORD must be set." + exit 0 +fi + +MARIADB_SSL_CMD_ARGS="" + +if [ "${MARIADB_SSL,,}" == "true" ]; then + log-helper info "SSL config..." + + # generate a certificate and key with ssl-helper if MARIADB_SSL_CRT_FILENAME and MARIADB_SSL_KEY_FILENAME files don't exists + # https://github.com/osixia/docker-light-baseimage/blob/stable/image/service-available/:ssl-tools/assets/tool/ssl-helper + ssl-helper ${MARIADB_SSL_HELPER_PREFIX} "${CONTAINER_SERVICE_DIR}/mariadb-helper/assets/certs/$MARIADB_SSL_CRT_FILENAME" "${CONTAINER_SERVICE_DIR}/mariadb-helper/assets/certs/$MARIADB_SSL_KEY_FILENAME" "${CONTAINER_SERVICE_DIR}/mariadb-helper/assets/certs/$MARIADB_SSL_CA_CRT_FILENAME" + + MARIADB_SSL_CMD_ARGS="--ssl --ssl-ca ${CONTAINER_SERVICE_DIR}/mariadb-helper/assets/certs/$MARIADB_SSL_CA_CRT_FILENAME --ssl-cert ${CONTAINER_SERVICE_DIR}/mariadb-helper/assets/certs/$MARIADB_SSL_CRT_FILENAME --ssl-key ${CONTAINER_SERVICE_DIR}/mariadb-helper/assets/certs/$MARIADB_SSL_KEY_FILENAME --ssl-cipher ${MARIADB_SSL_CIPHER_SUITE}" +fi + +MARIADB_CMD_ARGS="-h${MARIADB_HOST} -u${MARIADB_ROOT_USER} -p${MARIADB_ROOT_PASSWORD} ${MARIADB_SSL_CMD_ARGS}" + +log-helper info "Creating database ${MARIADB_TO_DATABASE} on host ${MARIADB_HOST}..." +mysqladmin ${MARIADB_CMD_ARGS} create ${MARIADB_TO_DATABASE} + +CREATE_CMD_RESULT=$? + +if [ $CREATE_CMD_RESULT -eq 255 ]; then + log-helper info "Database ${MARIADB_TO_DATABASE} already exists." + exit 0 +elif [ $CREATE_CMD_RESULT -eq 0 ]; then + log-helper info "Database ${MARIADB_TO_DATABASE} created." + + if [ -n "${MARIADB_TO_DATABASE_GRANT_USER}" ]; then + log-helper info "Grant user ${MARIADB_TO_DATABASE_GRANT_USER} permissions on database ${MARIADB_TO_DATABASE}..." + mysql ${MARIADB_CMD_ARGS} -e "GRANT ${MARIADB_TO_DATABASE_GRANT_PRIVILEGES} ON \`${MARIADB_TO_DATABASE}\`.* TO '${MARIADB_TO_DATABASE_GRANT_USER}'@'${MARIADB_TO_DATABASE_GRANT_USER_HOST}' ;" ${MARIADB_TO_DATABASE} + fi + + if [ -n "${MARIADB_FROM_DATABASE_REGEX}" ]; then + log-helper debug "Use regex ${MARIADB_FROM_DATABASE_REGEX} on ${MARIADB_TO_DATABASE}" + + if ! [[ ${MARIADB_TO_DATABASE} =~ ${MARIADB_FROM_DATABASE_REGEX} ]]; then + log-helper error "Enable to extract database name." + exit 1 + else + MARIADB_FROM_DATABASE="${BASH_REMATCH[1]}${MARIADB_FROM_DATABASE}" + fi + fi + + if [ "${MARIADB_FROM_DATABASE}" == "${MARIADB_TO_DATABASE}" ]; then + log-helper warning "MARIADB_FROM_DATABASE == MARIADB_TO_DATABASE == ${MARIADB_TO_DATABASE} copy aborted." + else + log-helper info "Copying database ${MARIADB_FROM_DATABASE} to ${MARIADB_TO_DATABASE}..." + mysqldump ${MARIADB_CMD_ARGS} --no-create-db --events --triggers --routines --compress ${MARIADB_FROM_DATABASE} | mysql ${MARIADB_CMD_ARGS} ${MARIADB_TO_DATABASE} + fi + +else + log-helper info "Error." + exit 1 +fi + +log-helper info "Done." + +exit 0 diff --git a/test/test.bats b/test/test.bats new file mode 100644 index 0000000..fb7fc13 --- /dev/null +++ b/test/test.bats @@ -0,0 +1,9 @@ +#!/usr/bin/env bats +load test_helper + +@test "image build" { + + run build_image + [ "$status" -eq 0 ] + +} diff --git a/test/test_helper.bash b/test/test_helper.bash new file mode 100644 index 0000000..21dd8f4 --- /dev/null +++ b/test/test_helper.bash @@ -0,0 +1,75 @@ +setup() { + IMAGE_NAME="$NAME:$VERSION" +} + +# function relative to the current container / image +build_image() { + #disable outputs + docker build -t $IMAGE_NAME $BATS_TEST_DIRNAME/../image &> /dev/null +} + +run_image() { + CONTAINER_ID=$(docker run $@ -d $IMAGE_NAME -c "/container/service/mariadb/test.sh") + CONTAINER_IP=$(get_container_ip_by_cid $CONTAINER_ID) +} + +start_container() { + start_containers_by_cid $CONTAINER_ID +} + +stop_container() { + stop_containers_by_cid $CONTAINER_ID +} + +remove_container() { + remove_containers_by_cid $CONTAINER_ID +} + +clear_container() { + stop_containers_by_cid $CONTAINER_ID + remove_containers_by_cid $CONTAINER_ID +} + +wait_process() { + wait_process_by_cid $CONTAINER_ID $@ +} + +# generic functions +get_container_ip_by_cid() { + local IP=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" $1) + echo "$IP" +} + +start_containers_by_cid() { + for cid in "$@" + do + #disable outputs + docker start $cid &> /dev/null + done +} + +stop_containers_by_cid() { + for cid in "$@" + do + #disable outputs + docker stop $cid &> /dev/null + done +} + +remove_containers_by_cid() { + for cid in "$@" + do + #disable outputs + docker rm $cid &> /dev/null + done +} + +clear_containers_by_cid() { + stop_containers_by_cid $@ + remove_containers_by_cid $@ +} + +wait_process_by_cid() { + cid=$1 + docker exec $cid /container/tool/wait-process ${@:2} +}