|
| 1 | +package main |
| 2 | + |
| 3 | +// #!/usr/bin/env bash |
| 4 | +// # |
| 5 | +// # builder hook called on every git receive-pack |
| 6 | +// # NOTE: this script must be run as root (for docker access) |
| 7 | +// # |
| 8 | +// set -eo pipefail |
| 9 | +// |
| 10 | +// ARGS=3 |
| 11 | +// HOST=`ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'` |
| 12 | +// indent() { |
| 13 | +// echo " $@" |
| 14 | +// } |
| 15 | +// |
| 16 | +// puts-step() { |
| 17 | +// echo "-----> $@" |
| 18 | +// } |
| 19 | +// |
| 20 | +// puts-step-sameline() { |
| 21 | +// echo -n "-----> $@" |
| 22 | +// } |
| 23 | +// |
| 24 | +// puts-warn() { |
| 25 | +// echo " ! $@" |
| 26 | +// } |
| 27 | +// |
| 28 | +// usage() { |
| 29 | +// echo "Usage: $0 <user> <repo> <sha>" |
| 30 | +// } |
| 31 | +// |
| 32 | +// parse-string(){ |
| 33 | +// # helper to avoid the single quote escape |
| 34 | +// # occurred in command substitution |
| 35 | +// local args=() idx=0 IFS=' ' c |
| 36 | +// for c; do printf -v args[idx++] '%s ' "$c"; done |
| 37 | +// printf "%s\n" "${args[*]}" |
| 38 | +// } |
| 39 | +// |
| 40 | +// if [ $# -ne $ARGS ]; then |
| 41 | +// usage |
| 42 | +// exit 1 |
| 43 | +// fi |
| 44 | +// |
| 45 | +// USER=$1 |
| 46 | +// REPO=$2 |
| 47 | +// GIT_SHA=$3 |
| 48 | +// SHORT_SHA=${GIT_SHA:0:8} |
| 49 | +// APP_NAME="${REPO%.*}" |
| 50 | +// |
| 51 | +// cd $(dirname $0) # ensure we are in the root dir |
| 52 | +// |
| 53 | +// ROOT_DIR=$(pwd) |
| 54 | +// REPO_DIR="${ROOT_DIR}/${REPO}" |
| 55 | +// BUILD_DIR="${REPO_DIR}/build" |
| 56 | +// CACHE_DIR="${REPO_DIR}/cache" |
| 57 | +// |
| 58 | +// # define image names |
| 59 | +// SLUG_NAME="$APP_NAME:git-$SHORT_SHA" |
| 60 | +// META_NAME=`echo ${SLUG_NAME}| tr ":" "-"` |
| 61 | +// TMP_IMAGE="$DEIS_REGISTRY_SERVICE_HOST:$DEIS_REGISTRY_SERVICE_PORT/$IMAGE_NAME" |
| 62 | +// # create app directories |
| 63 | +// mkdir -p $BUILD_DIR $CACHE_DIR |
| 64 | +// # create temporary directory inside the build dir for this push |
| 65 | +// TMP_DIR=$(mktemp -d -p $BUILD_DIR) |
| 66 | +// |
| 67 | +// cd $REPO_DIR |
| 68 | +// # use Procfile if provided, otherwise try default process types from ./release |
| 69 | +// git archive --format=tar.gz ${GIT_SHA} > ${APP_NAME}.tar.gz |
| 70 | +// tar -xzf ${APP_NAME}.tar.gz -C $TMP_DIR/ |
| 71 | +// USING_DOCKERFILE=true |
| 72 | +// if [ -f $TMP_DIR/Procfile ]; then |
| 73 | +// PROCFILE=$(cat $TMP_DIR/Procfile | yaml2json-procfile) |
| 74 | +// USING_DOCKERFILE=false |
| 75 | +// else |
| 76 | +// PROCFILE="{}" |
| 77 | +// fi |
| 78 | +// |
| 79 | +// if [[ ! -f /var/run/secrets/object/store/access-key-id ]]; then |
| 80 | +// if $USING_DOCKERFILE ; then |
| 81 | +// l1=`grep -n "object-store" /etc/deis-dockerbuilder.yaml | head -n1 |cut -d ":" -f1` |
| 82 | +// l2=$(($l1+3)) |
| 83 | +// sed "$l1,$l2 d" /etc/deis-dockerbuilder.yaml > /etc/${SLUG_NAME}.yaml.tmp |
| 84 | +// l1=`grep -n "object-store" /etc/deis-dockerbuilder.yaml.tmp | head -n1 |cut -d ":" -f1` |
| 85 | +// l2=$(($l1+3)) |
| 86 | +// sed "$l1,$l2 d" /etc/${SLUG_NAME}.yaml.tmp > /etc/${SLUG_NAME}.yaml |
| 87 | +// sed -i -- "s#repo_name#$TMP_IMAGE#g" /etc/${SLUG_NAME}.yaml |
| 88 | +// else |
| 89 | +// head -n 21 /etc/deis-slugbuilder.yaml > /etc/${SLUG_NAME}.yaml |
| 90 | +// fi |
| 91 | +// else |
| 92 | +// if $USING_DOCKERFILE ; then |
| 93 | +// cp /etc/deis-dockerbuilder.yaml /etc/${SLUG_NAME}.yaml |
| 94 | +// sed -i -- "s#repo_name#$TMP_IMAGE#g" /etc/${SLUG_NAME}.yaml |
| 95 | +// else |
| 96 | +// cp /etc/deis-slugbuilder.yaml /etc/${SLUG_NAME}.yaml |
| 97 | +// fi |
| 98 | +// fi |
| 99 | +// |
| 100 | +// git archive --format=tar.gz ${GIT_SHA} > ${APP_NAME}.tar.gz |
| 101 | +// |
| 102 | +// HTTP_PREFIX="http" |
| 103 | +// REMOTE_STORAGE="0" |
| 104 | +// # if minio is in the cluster, use it. otherwise use fetcher |
| 105 | +// # TODO: figure out something for using S3 also |
| 106 | +// if [[ -n "$DEIS_MINIO_SERVICE_HOST" && -n "$DEIS_MINIO_SERVICE_PORT" ]]; then |
| 107 | +// S3EP=${DEIS_MINIO_SERVICE_HOST}:${DEIS_MINIO_SERVICE_PORT} |
| 108 | +// REMOTE_STORAGE="1" |
| 109 | +// elif [[ -n "$DEIS_OUTSIDE_STORAGE_HOST" && -n "$DEIS_OUTSIDE_STORAGE_PORT" ]]; then |
| 110 | +// HTTP_PREFIX="https" |
| 111 | +// S3EP=${DEIS_OUTSIDE_STORAGE_HOST}:${DEIS_OUTSIDE_STORAGE_PORT} |
| 112 | +// REMOTE_STORAGE="1" |
| 113 | +// elif [ -z "$S3EP" ]; then |
| 114 | +// S3EP=${HOST}:3000 |
| 115 | +// fi |
| 116 | +// |
| 117 | +// TAR_URL=$HTTP_PREFIX://$S3EP/git/home/${SLUG_NAME}/tar |
| 118 | +// PUSH_URL=$HTTP_PREFIX://$S3EP/git/home/${SLUG_NAME}/push |
| 119 | +// |
| 120 | +// sed -i -- "s#repo_name#$META_NAME#g" /etc/${SLUG_NAME}.yaml |
| 121 | +// sed -i -- "s#puturl#$PUSH_URL#g" /etc/${SLUG_NAME}.yaml |
| 122 | +// sed -i -- "s#tar-url#$TAR_URL#g" /etc/${SLUG_NAME}.yaml |
| 123 | +// |
| 124 | +// ACCESS_KEY=`cat /var/run/secrets/object/store/access-key-id` |
| 125 | +// ACCESS_SECRET=`cat /var/run/secrets/object/store/access-secret-key` |
| 126 | +// # copy the self signed cert into the CA directory for alpine. |
| 127 | +// # note: we're not running minio with SSL at all right now, so no need for this. |
| 128 | +// # future SSL rollouts for in-cluster storage may not need it either if we set up an intermediate CA |
| 129 | +// # CERT_FILE="/var/run/secrets/object/ssl/access-cert" |
| 130 | +// # cp $CERT_FILE /etc/ssl/certs/deis-minio-self-signed-cert.crt |
| 131 | +// mkdir -p /var/minio-conf |
| 132 | +// CONFIG_DIR=/var/minio-conf |
| 133 | +// MC_PREFIX="mc -C $CONFIG_DIR --quiet" |
| 134 | +// $MC_PREFIX config host add "$HTTP_PREFIX://$S3EP" $ACCESS_KEY $ACCESS_SECRET &>/dev/null |
| 135 | +// $MC_PREFIX mb "$HTTP_PREFIX://${S3EP}/git" &>/dev/null |
| 136 | +// $MC_PREFIX cp ${APP_NAME}.tar.gz $TAR_URL &>/dev/null |
| 137 | +// |
| 138 | +// puts-step "Starting build" |
| 139 | +// kubectl --namespace=${POD_NAMESPACE} create -f /etc/${SLUG_NAME}.yaml >/dev/null |
| 140 | +// |
| 141 | +// # wait for pod to be running and then pull its logs |
| 142 | +// until [ "`kubectl --namespace=${POD_NAMESPACE} get pods -o yaml ${META_NAME} | grep "phase: " | awk {'print $2'}`" == "Running" ]; do |
| 143 | +// sleep 0.1 |
| 144 | +// done |
| 145 | +// kubectl --namespace=${POD_NAMESPACE} logs -f ${META_NAME} 2>/dev/null & |
| 146 | +// |
| 147 | +// #check for image creation or slug existence in S3EP |
| 148 | +// |
| 149 | +// if [[ "$REMOTE_STORAGE" == "1" ]]; then |
| 150 | +// LS_CMD="$MC_PREFIX ls $PUSH_URL" |
| 151 | +// until $LS_CMD &> /dev/null; do |
| 152 | +// echo -ne "." |
| 153 | +// sleep 2 |
| 154 | +// done |
| 155 | +// else |
| 156 | +// while [ ! -f /apps/${SLUG_NAME}/slug.tgz ] |
| 157 | +// do |
| 158 | +// echo -ne "." |
| 159 | +// sleep 2 |
| 160 | +// done |
| 161 | +// fi |
| 162 | +// |
| 163 | +// # build completed |
| 164 | +// |
| 165 | +// puts-step "Build complete." |
| 166 | +// puts-step "Launching app." |
| 167 | +// |
| 168 | +// URL="http://$DEIS_WORKFLOW_SERVICE_HOST:$DEIS_WORKFLOW_SERVICE_PORT/v2/hooks/config" |
| 169 | +// RESPONSE=$(get-app-config -url="$URL" -key="{{ getv "/deis/controller/builderKey" }}" -user=$USER -app=$APP_NAME) |
| 170 | +// CODE=$? |
| 171 | +// if [ $CODE -ne 0 ]; then |
| 172 | +// puts-warn $RESPONSE |
| 173 | +// exit 1 |
| 174 | +// fi |
| 175 | +// |
| 176 | +// # use Procfile if provided, otherwise try default process types from ./release |
| 177 | +// |
| 178 | +// puts-step "Launching... " |
| 179 | +// URL="http://$DEIS_WORKFLOW_SERVICE_HOST:$DEIS_WORKFLOW_SERVICE_PORT/v2/hooks/build" |
| 180 | +// DATA="$(generate-buildhook "$SHORT_SHA" "$USER" "$APP_NAME" "$APP_NAME" "$PROCFILE" "$USING_DOCKERFILE")" |
| 181 | +// PUBLISH_RELEASE=$(echo "$DATA" | publish-release-controller -url=$URL -key={{ getv "/deis/controller/builderKey" }}) |
| 182 | +// CODE=$? |
| 183 | +// if [ $CODE -ne 0 ]; then |
| 184 | +// puts-warn "ERROR: Failed to launch container" |
| 185 | +// puts-warn $PUBLISH_RELEASE |
| 186 | +// exit 1 |
| 187 | +// fi |
| 188 | +// |
| 189 | +// RELEASE=$(echo $PUBLISH_RELEASE | extract-version) |
| 190 | +// DOMAIN=$(echo $PUBLISH_RELEASE | extract-domain) |
| 191 | +// indent "done, $APP_NAME:v$RELEASE deployed to Deis" |
| 192 | +// echo |
| 193 | +// indent "http://$DOMAIN" |
| 194 | +// echo |
| 195 | +// indent "To learn more, use \`deis help\` or visit http://deis.io" |
| 196 | +// echo |
| 197 | +// |
| 198 | +// # cleanup |
| 199 | +// cd $REPO_DIR |
| 200 | +// git gc &>/dev/null |
0 commit comments