|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +set -e |
| 4 | +set -x |
| 5 | + |
| 6 | +ME=$0 |
| 7 | +COMMAND=$1 |
| 8 | + |
| 9 | +function show-help() { |
| 10 | + echo "Valid commands:" |
| 11 | + echo " init" |
| 12 | + echo " push" |
| 13 | +} |
| 14 | + |
| 15 | +function get_s3_bucket_location() { |
| 16 | + BUCKET=$1 |
| 17 | + |
| 18 | + echo "Locating S3 bucket ${BUCKET}..." |
| 19 | + local bucket_region=`aws --output text s3api get-bucket-location --bucket ${BUCKET}` |
| 20 | + local url_base=https://s3-${bucket_region}.amazonaws.com/${BUCKET} |
| 21 | + |
| 22 | + # us-east-1 does not fit the pattern |
| 23 | + if [[ "${bucket_region}" == "None" ]]; then |
| 24 | + bucket_region="us-east-1" |
| 25 | + url_base=https://s3.amazonaws.com/${BUCKET} |
| 26 | + fi |
| 27 | + |
| 28 | + S3_BUCKET_REGION=${bucket_region} |
| 29 | + S3_URL_BASE=${url_base} |
| 30 | +} |
| 31 | + |
| 32 | +function command-init() { |
| 33 | + PREFIX=$1 |
| 34 | + REPO=$2 |
| 35 | + |
| 36 | + if [[ -z "${PREFIX}" || -z "${REPO}" ]]; then |
| 37 | + echo "syntax: $ME init <prefix> <repo>" |
| 38 | + echo "For example, $ME init aci.mydomain.com s3://aci.mydomain.com" |
| 39 | + exit 1 |
| 40 | + fi |
| 41 | + |
| 42 | + if [[ "${REPO}" == s3://* ]]; then |
| 43 | + BUCKET=${REPO:5} |
| 44 | + |
| 45 | + # TODO: Create bucket automatically? |
| 46 | + BUILD=.build |
| 47 | + mkdir -p ${BUILD} |
| 48 | + |
| 49 | + if [[ ! -f ${BUILD}/pubkeys.gpg ]]; then |
| 50 | + echo "Exporting public keys" |
| 51 | + gpg --armor --export --output .build/pubkeys.gpg |
| 52 | + fi |
| 53 | + |
| 54 | + cat <<EOF >${BUILD}/index.html |
| 55 | +<html> |
| 56 | +<head> |
| 57 | +<meta name="ac-discovery" content="${PREFIX} http://${PREFIX}/{os}/{arch}/{name}-{version}.{ext}"> |
| 58 | +<meta name="ac-discovery-pubkeys" content="${PREFIX} pubkeys.gpg"> |
| 59 | +</head> |
| 60 | +<body> |
| 61 | +</body> |
| 62 | +</html> |
| 63 | +EOF |
| 64 | + get_s3_bucket_location ${BUCKET} |
| 65 | + trust_url=${S3_URL_BASE}/pubkeys.gpg |
| 66 | + |
| 67 | + # TODO: Non-public repos? |
| 68 | + is_website=1 |
| 69 | + aws --region ${S3_BUCKET_REGION} s3api get-bucket-website --bucket ${BUCKET} >/dev/null 2>&1 || is_website=0 |
| 70 | + if [[ ${is_website} == 0 ]]; then |
| 71 | + echo "Making bucket website-accesible" |
| 72 | + aws --region ${S3_BUCKET_REGION} s3api put-bucket-website --cli-input-json '{ "WebsiteConfiguration": { "IndexDocument": { "Suffix": "index.html" } } }' --bucket ${BUCKET} |
| 73 | + fi |
| 74 | + |
| 75 | + aws --region ${S3_BUCKET_REGION} s3 cp --acl public-read ${BUILD}/pubkeys.gpg s3://${BUCKET}/ |
| 76 | + aws --region ${S3_BUCKET_REGION} s3 cp --acl public-read ${BUILD}/index.html s3://${BUCKET}/ |
| 77 | + else |
| 78 | + echo "Unknown repo schema: ${REPO}" |
| 79 | + echo "Please specify the repo like s3://<bucketname>" |
| 80 | + exit 1 |
| 81 | + fi |
| 82 | + |
| 83 | + echo "Trust the repo using:" |
| 84 | + echo "rkt trust --prefix ${PREFIX} ${trust_url}" |
| 85 | +} |
| 86 | + |
| 87 | +function command-push() { |
| 88 | + IMAGE=$1 |
| 89 | + REPO=$2 |
| 90 | + |
| 91 | + if [[ -z "${IMAGE}" || -z "${REPO}" ]]; then |
| 92 | + echo "syntax: $ME push <image> <repo>" |
| 93 | + echo "For example, $ME push imagedir/myimage.aci s3://aci.mydomain.com" |
| 94 | + exit 1 |
| 95 | + fi |
| 96 | + |
| 97 | + if [[ ! -f "${IMAGE}" ]]; then |
| 98 | + echo "Image not found: ${IMAGE}" |
| 99 | + exit 1 |
| 100 | + fi |
| 101 | + |
| 102 | + SIG=${IMAGE}.asc |
| 103 | + |
| 104 | + MANIFEST=`actool cat-manifest ${IMAGE}` |
| 105 | + |
| 106 | + IMAGE_NAME=`echo "${MANIFEST}" | python -c 'import json,sys;o=json.load(sys.stdin);print o["name"]'` |
| 107 | + if [[ -z "${IMAGE_NAME}" ]]; then |
| 108 | + echo "Image name could not be parsed from manifest" |
| 109 | + exit 1 |
| 110 | + fi |
| 111 | + |
| 112 | + IMAGE_VERSION=`echo "${MANIFEST}" | python -c 'import json,sys;o=json.load(sys.stdin);print o["acVersion"]'` |
| 113 | + if [[ -z "${IMAGE_VERSION}" ]]; then |
| 114 | + echo "Image version could not be parsed from manifest" |
| 115 | + exit 1 |
| 116 | + fi |
| 117 | + |
| 118 | + echo "Using image name: ${IMAGE_NAME}, version: ${IMAGE_VERSION}" |
| 119 | + |
| 120 | + if [[ ! -f "${SIG}" ]]; then |
| 121 | + echo "Signature file not found; signing" |
| 122 | + gpg --armor --output ${SIG} --detach-sign ${IMAGE} |
| 123 | + fi |
| 124 | + |
| 125 | + if [[ "${REPO}" == s3://* ]]; then |
| 126 | + BUCKET=${REPO:5} |
| 127 | + |
| 128 | + get_s3_bucket_location ${BUCKET} |
| 129 | + |
| 130 | + target=linux/amd64/${IMAGE_NAME}-${IMAGE_VERSION}.aci |
| 131 | + run_url=${S3_URL_BASE}/${target} |
| 132 | + |
| 133 | + echo "Uploading image to s3://${BUCKET}/${target}" |
| 134 | + aws --region ${S3_BUCKET_REGION} s3 cp --acl public-read ${IMAGE} s3://${BUCKET}/${target} |
| 135 | + |
| 136 | + echo "Uploading signature to s3://${BUCKET}/${target}.asc" |
| 137 | + aws --region ${S3_BUCKET_REGION} s3 cp --acl public-read ${SIG} s3://${BUCKET}/${target}.asc |
| 138 | + else |
| 139 | + echo "Unknown repo schema: ${REPO}" |
| 140 | + echo "Please specify the repo like s3://<bucketname>" |
| 141 | + exit 1 |
| 142 | + fi |
| 143 | + |
| 144 | + echo "Image uploaded" |
| 145 | + echo "Run the image with: rkt run ${run_url}" |
| 146 | + echo "or, if you have set up a CNAME for the bucket:" |
| 147 | + echo "rkt run ${IMAGE_NAME}@${IMAGE_VERSION}" |
| 148 | +} |
| 149 | + |
| 150 | +if [[ -z "${COMMAND}" ]]; then |
| 151 | + echo "syntax: $ME <command> <args...>" |
| 152 | + show-help |
| 153 | + exit 1 |
| 154 | +fi |
| 155 | + |
| 156 | +shift |
| 157 | + |
| 158 | +case $COMMAND in |
| 159 | + init) |
| 160 | + command-init $@ |
| 161 | + ;; |
| 162 | + push) |
| 163 | + command-push $@ |
| 164 | + ;; |
| 165 | + help) |
| 166 | + show-help |
| 167 | + ;; |
| 168 | + *) |
| 169 | + echo "Unknown command: ${COMMAND}" |
| 170 | + show-help |
| 171 | + exit 1 |
| 172 | + ;; |
| 173 | +esac |
| 174 | +exit 0 |
| 175 | + |
| 176 | +if [[ -z "${PREFIX}" || -z "${REPO}" ]]; then |
| 177 | + echo "syntax: $0 <prefix> <repo>" |
| 178 | + echo "For example, $0 aci.mydomain.com s3://aci.mydomain.com" |
| 179 | + exit 1 |
| 180 | +fi |
| 181 | + |
| 182 | +if [[ "${REPO}" == s3://* ]]; then |
| 183 | + BUCKET=${REPO:5} |
| 184 | + |
| 185 | + # TODO: Create bucket automatically? |
| 186 | + |
| 187 | + echo "Locating bucket..." |
| 188 | + bucket_region=`aws --output text s3api get-bucket-location --bucket ${BUCKET}` |
| 189 | + url_base=https://s3-${bucket_region}.amazonaws.com/${BUCKET} |
| 190 | + |
| 191 | + # us-east-1 does not fit the pattern |
| 192 | + if [[ "${bucket_region}" == "None" ]]; then |
| 193 | + bucket_region="us-east-1" |
| 194 | + url_base=https://s3.amazonaws.com/${BUCKET} |
| 195 | + fi |
| 196 | + |
| 197 | + mkdir -p .build/ |
| 198 | + |
| 199 | + if [[ ! -f .build/pubkeys.gpg ]]; then |
| 200 | + echo "Exporting public keys" |
| 201 | + gpg --armor --export --output .build/pubkeys.gpg |
| 202 | + fi |
| 203 | + |
| 204 | + cat <<EOF >.build/index.html |
| 205 | +<html> |
| 206 | +<head> |
| 207 | +<meta name="ac-discovery" content="${PREFIX} http://${PREFIX}/{os}/{arch}/{name}-{version}.{ext}"> |
| 208 | +<meta name="ac-discovery-pubkeys" content="${PREFIX} pubkeys.gpg"> |
| 209 | +</head> |
| 210 | +<body> |
| 211 | +</body> |
| 212 | +</html> |
| 213 | +EOF |
| 214 | + |
| 215 | + trust_url=${url_base}/${target} |
| 216 | + |
| 217 | + aws --region ${bucket_region} s3 cp --acl public-read .build/pubkeys.gpg s3://${BUCKET}/ |
| 218 | + aws --region ${bucket_region} s3 cp --acl public-read .build/index.html s3://${BUCKET}/ |
| 219 | +else |
| 220 | + echo "Unknown repo schema: ${REPO}" |
| 221 | + echo "Please specify the repo like s3://<bucketname>" |
| 222 | + exit 1 |
| 223 | +fi |
| 224 | + |
| 225 | +echo "Trust the repo using:" |
| 226 | +echo "rkt trust --prefix ${PREFIX} ${url_base}/pubkeys.gpg" |
| 227 | + |
0 commit comments