diff --git a/Changelog.md b/Changelog.md index 709b02a8408c0d385a0484d645dccbda1971e2c4..d9b966ae99f392818599ab47f13ce793f6e9cce4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,15 @@ # Changelog +## [1.4.0] - 2019-03-13 +### Added +* new command `init` to only initialize docker, helm and kubectl +* `--reset` flag to remove eventually existing config-folders + +### Changed +* updated helm from 2.12.3 to 2.13.0 +* script now runs as non-root user +* removed namespace from kubectl-context and added it explicitely to helm + ## [1.3.2] - 2019-02-21 ### Changed * updated helm from 2.9.1 to 2.12.3 @@ -60,4 +70,5 @@ [1.2.4]: https://git.sc.uni-leipzig.de/ubl/bdd_dev/webmasterei/deployer/compare/release%2F1.2.3...release%2F1.2.4 [1.3.0]: https://git.sc.uni-leipzig.de/ubl/bdd_dev/webmasterei/deployer/compare/release%2F1.2.4...release%2F1.3.0 [1.3.1]: https://git.sc.uni-leipzig.de/ubl/bdd_dev/webmasterei/deployer/compare/release%2F1.3.0...release%2F1.3.1 -[1.3.2]: https://git.sc.uni-leipzig.de/ubl/bdd_dev/webmasterei/deployer/compare/release%2F1.3.1...release%2F1.3.2 \ No newline at end of file +[1.3.2]: https://git.sc.uni-leipzig.de/ubl/bdd_dev/webmasterei/deployer/compare/release%2F1.3.1...release%2F1.3.2 +[1.4.0]: https://git.sc.uni-leipzig.de/ubl/bdd_dev/webmasterei/deployer/compare/release%2F1.3.2...release%2F1.4.0 diff --git a/Dockerfile b/Dockerfile index 0f2842062fd3eae7aa8c10ae7cd4c60d42116636..3d07374f06589f50818eaeac7bf10c280b9f078b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,14 @@ FROM docker:latest COPY assets/deployer /usr/local/bin/ WORKDIR /app + +ENV APP_USER=deployer + RUN apk add --no-cache bash curl \ && curl -L https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl >/usr/local/bin/kubectl \ - && curl -L https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz | tar -zxf - -C /tmp linux-amd64/helm -O >/usr/local/bin/helm \ - && chmod a+x /usr/local/bin/deployer /usr/local/bin/kubectl /usr/local/bin/helm \ No newline at end of file + && curl -L https://storage.googleapis.com/kubernetes-helm/helm-v2.13.0-linux-amd64.tar.gz | tar -zxf - -C /tmp linux-amd64/helm -O >/usr/local/bin/helm \ + && chmod a+x /usr/local/bin/deployer /usr/local/bin/kubectl /usr/local/bin/helm \ + && addgroup -S ${APP_USER} \ + && adduser -S -h /home/${APP_USER} -G ${APP_USER} -s /bin/sh ${APP_USER} + +USER deployer \ No newline at end of file diff --git a/Readme.md b/Readme.md index b79cb16e0467356cb796ae588ce5ea05ae7172bf..9d7a0acaa760508c60f7436d7c5a24dea1af210c 100644 --- a/Readme.md +++ b/Readme.md @@ -88,11 +88,26 @@ From now on charts located in this repository can be deployed by using the `--ch # Advanced Configuration +## docker init + + ## docker build +* `--docker-config`: sets the content of the file `~/.docker/config.json` which is used by docker to authenticate to the registry. This can contain multiple registry-servers and there credentials. Which registry is used depends on the image name. * `--build-arg`: used to provide build-arguments do `docker build`-command. This is mainly used for `HTTP_PROXY`/`http_proxy`: When you specify `--build-arg HTTP_PROXY=...` the tool adds the build argument `--build-arg http_proxy=...` as well, so lower-case proxy-variables are provided automatically. Nevertheless can you use this option to provide your own build-arguments within the `Dockerfile` -* `--output`: sets the filepath to the file where the built image is saved. If omitted the image is not saved to a file +* `--output`: sets the filepath to the file where the built image is saved. If omitted the image is not saved to a file. Also the script trys to import an eventually existing file prior to building in order to make usage of its layers as build-cache. * `--build-context`: sets the build-context for `docker build` to a custom path. If omitted the path where the command is invoked is used. +* `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. + +## docker init + +* `--docker-config`: sets the content of the file `~/.docker/config.json` which is used by docker to authenticate to the registry. This can contain multiple registry-servers and there credentials. Which registry is used depends on the image name. +* `--cluster-url`: sets the url to the kube-apiserver. This URL is provided by the k8s-admin. +* `--certificate-authority`: sets the certificate-authority certificate as base64-encoded string. This string is provided by the k8s-admin +* `--token`: sets the bearer token of the service-account as bas64-encoded string. This string is provided by the k8s-admin. +* `--namespace`: sets the k8s-namespace where the deployment is located. This string is provided by the k8s-admin. +* `--service-account`: this is the name of the service-account, that is used to perform the deployment. +* `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. ## docker publish @@ -100,6 +115,7 @@ From now on charts located in this repository can be deployed by using the `--ch * `--docker-config`: sets the content of the file `~/.docker/config.json` which is used by docker to authenticate to the registry. This can contain multiple registry-servers and there credentials. Which registry is used depends on the image name. * `--name`: sets the name of the image. If you do not wish to publish to [Docker-Hub], you have to specify a server, e.g. `registry.example.com/my-image`. **Be aware that you need to provide credentials in your docker-config if the registry requires authentication. * `--tags`: sets the tags of the image. Provide multiple `--tag`-options if you wish to tag an image with multiple tags. +* `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. ## docker deploy @@ -114,6 +130,7 @@ From now on charts located in this repository can be deployed by using the `--ch * `--set`: overrides the values from `Values.yaml` in the helm-charts. Provide multiple `--set`-options if you want to provide multiple overrides. * `--set-string`: overrides the values from `Values.yaml` in the helm-charts as string. Provide multiple `--set-string`-options if you want to provide multiple overrides. * `--timeout`: sets the timeout for helm. defaults to `60` seconds. +* `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. ## docker undeploy @@ -123,6 +140,7 @@ From now on charts located in this repository can be deployed by using the `--ch * `--namespace`: sets the k8s-namespace where the deployment is located. This string is provided by the k8s-admin. * `--service-account`: this is the name of the service-account, that is used to perform the deployment. This string is provided by the k8s-admin * `--name`: sets the name of the deployment. +* `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. ## docker add-repo @@ -133,6 +151,7 @@ From now on charts located in this repository can be deployed by using the `--ch * `--service-account`: this is the name of the service-account, that is used to perform the deployment. This string is provided by the k8s-admin * `--name`: sets the name of the repo to add. * `--repo-url`: sets the repository-url of the repo to add. +* `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. # Assumptions diff --git a/assets/deployer b/assets/deployer index 6ebe4b32c2f9c658c735393b00c39f676fed4bd1..c2883e16a28f91eb55ebe796daa72ebc6e0e9db7 100755 --- a/assets/deployer +++ b/assets/deployer @@ -23,6 +23,7 @@ service_account="" repo_url="" build_context="." timeout="60" +reset="" ! getopt --test > /dev/null if [[ ${PIPESTATUS[0]} -ne 4 ]]; then @@ -31,7 +32,7 @@ if [[ ${PIPESTATUS[0]} -ne 4 ]]; then fi OPTIONS= -LONGOPTS=docker-config:,tag:,build-arg:,values:,set:,set-string:,charts:,name:,token:,certificate-authority:,namespace:,cluster-url:,service-account:,output:,input:,repo-url:,build-context:,timeout: +LONGOPTS=docker-config:,tag:,build-arg:,values:,set:,set-string:,charts:,name:,token:,certificate-authority:,namespace:,cluster-url:,service-account:,output:,input:,repo-url:,build-context:,timeout:,reset # -use ! and PIPESTATUS to get exit code with errexit set # -temporarily store output to be able to check for errors @@ -109,6 +110,10 @@ while true; do timeout="$2" shift 2 ;; + --reset) + reset="true" + shift + ;; --) shift break @@ -147,12 +152,18 @@ prepare_kubectl() { echo "Please be sure to provide a service-account via --service-account" fi - out=`rm -rf ~/.kube` - if [ "$?" != "0" ];then - echo "failed" - echo "$out" - return 1 - fi; + if [ "${reset}" == "true" ];then + echo -ne " (removing .kube folder because \"--reset\" was provided)" + out=`rm -rf ${HOME}/.kube/*` + if [ "$?" != "0" ];then + echo "failed" + echo "$out" + return 1 + fi + elif [ -d "${HOME}/.kube" ];then + echo "folder .kube already exists. if you want to ignore it provide the \"--reset\" parameter. skipping" + return 0 + fi echo "" @@ -180,7 +191,7 @@ prepare_kubectl() { echo "done" echo -ne "\tSetting context..." - out=`kubectl config set-context "${context}" --user="${account}" --cluster="${cluster_name}" --namespace="${namespace}"` + out=`kubectl config set-context "${context}" --user="${account}" --cluster="${cluster_name}"` if [ "$?" != "0" ];then echo "failed" echo "$out" @@ -199,7 +210,7 @@ prepare_kubectl() { echo -ne "\tTesting context..." for resource in deployment service configmap;do - out=`kubectl auth can-i create $resource` + out=`kubectl --namespace="${namespace}" auth can-i create $resource` if [ "$?" != "0" ];then echo "failed" echo "$out" @@ -213,6 +224,20 @@ prepare_kubectl() { prepare_helm() { echo -ne "Preparing helm..." + + if [ "${reset}" == "true" ];then + echo -ne " (removing .helm folder because \"--reset\" was provided) ..." + out=`rm -rf ${HOME}/.helm/*` + if [ "$?" != "0" ];then + echo "failed" + echo "$out" + return 1 + fi + elif [ -d "${HOME}/.helm" ];then + echo "folder .helm already exists. if you want to ignore it provide the \"--reset\" parameter. skipping" + return 0 + fi + out=`helm init --wait --tiller-namespace="${namespace}" --service-account="${service_account}" --upgrade --force-upgrade` if [ "$?" != "0" ];then echo "failed!" @@ -279,7 +304,7 @@ helm_deploy() { fi helmargs=$(echo -e "$helmargs" | sed -E 's/(^[[:space:]]*)|([[:space:]]*$)//g') - cmd="helm upgrade --install --wait --timeout=${timeout} --tiller-namespace=${namespace}" + cmd="helm upgrade --install --wait --timeout=${timeout} --tiller-namespace=${namespace} --namespace=${namespace}" cmd="$cmd --namespace=${namespace} --recreate-pods ${name} ${charts} ${helmargs}" out=`$cmd 2>&1` @@ -322,7 +347,21 @@ prepare_image_publisher() { return 1 fi - rm -rf ~/.docker && mkdir -p ~/.docker && echo "${dockerconfig}" >~/.docker/config.json + if [ "${reset}" == "true" ];then + echo -ne " (removing .docker folder because \"--reset\" was provided) ..." + out=`rm -rf ${HOME}/.docker/*` + if [ "$?" != "0" ];then + echo "failed" + echo "$out" + return 1 + fi + elif [ -d "${HOME}/.docker" ];then + echo "folder .docker already exists. if you want to ignore it provide the \"--reset\" parameter. skipping" + return 0 + fi + + mkdir -p ${HOME}/.docker && echo "${dockerconfig}" >${HOME}/.docker/config.json + if [ "$?" != "0" ];then echo "failed" return 1 @@ -440,8 +479,11 @@ if [[ $# -ne 1 ]]; then fi case $1 in + init) + prepare_kubectl && prepare_helm && prepare_image_publisher + ;; build) - import_image && build_image && save_image + prepare_image_publisher && import_image && build_image && save_image ;; publish) prepare_image_publisher && import_image && publish_image diff --git a/docker-compose.yml b/docker-compose.yml index 0aee591782976305ed716f8ac777374ffeb2169e..145560f461907cca2e1d5497660fa5a32228b410 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,17 @@ version: '2' services: build: + build: . + volumes: + - ./:/app + - ./assets/deployer:/usr/local/bin/deployer + depends_on: + - docker + environment: + DOCKER_HOST: tcp://docker:2375 + command: deployer build --output .tmp/image.tar.gz + + init: build: . volumes: - ./:/app @@ -9,7 +20,35 @@ services: - docker environment: DOCKER_HOST: tcp://docker:2375 - command: deployer build --output .tmp/image.tar.gz + command: deployer init --namespace test --cluster-url https://172.18.85.125:6443 --certificate-authority ${ca_cert} --token ${token} --service-account test --docker-config "${docker_config}" + + init-with-existing: + build: . + volumes: + - ./:/app + - ./assets/deployer:/usr/local/bin/deployer + - ./.tmp/.kube:/home/deployer/.kube + - ./.tmp/.docker:/home/deployer/.docker + - ./.tmp/.helm:/home/deployer/.helm + depends_on: + - docker + environment: + DOCKER_HOST: tcp://docker:2375 + command: deployer init --namespace test --cluster-url https://172.18.85.125:6443 --certificate-authority ${ca_cert} --token ${token} --service-account test --docker-config "${docker_config}" + + init-with-existing-and-reset: + build: . + volumes: + - ./:/app + - ./assets/deployer:/usr/local/bin/deployer + - ./.tmp/.kube:/home/deployer/.kube + - ./.tmp/.docker:/home/deployer/.docker + - ./.tmp/.helm:/home/deployer/.helm + depends_on: + - docker + environment: + DOCKER_HOST: tcp://docker:2375 + command: deployer init --namespace test --cluster-url https://172.18.85.125:6443 --certificate-authority ${ca_cert} --token ${token} --service-account test --docker-config "${docker_config}" --reset build-no-save: build: .