-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrelease.sh
executable file
·255 lines (226 loc) · 7.65 KB
/
release.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#!/bin/bash
set -euo pipefail
# Default values.
AMI_DISK_SIZE=8192
AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-}"
AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-}"
AWS_SESSION_TOKEN="${AWS_SESSION_TOKEN:-}"
BOX_VERSION="$(date +%Y%m%d).0.0"
BOX_NAME=""
MEMSIZE=512
PROVISIONER=default
REGION="${AWS_DEFAULT_REGION:-us-east-1}"
USAGE="no"
VAGRANT_CLOUD_TOKEN="${VAGRANT_CLOUD_TOKEN:-}"
VAGRANT_CLOUD_TOKEN_FILE=""
VAGRANT_CLOUD_USER="hoot"
VMIMPORT_BUCKET=""
# Retrieving command-line options.
while getopts ":i:n:t:u:v:" opt; do
case "$opt" in
i)
VMIMPORT_BUCKET="$OPTARG"
;;
n)
BOX_NAME="$OPTARG"
;;
t)
VAGRANT_CLOUD_TOKEN_FILE="$OPTARG"
;;
u)
VAGRANT_CLOUD_USER="$OPTARG"
;;
v)
BOX_VERSION="$OPTARG"
;;
*)
USAGE=yes
;;
esac
done
shift $((OPTIND-1))
# Document the usage for this script.
function usage() {
echo "release.sh -n <Box Name> -i <VM Import S3 Bucket>"
echo " [-t <Vagrant Cloud Token JSON file>]"
echo " [-u <Vagrant Cloud User, default: '$VAGRANT_CLOUD_USER'>"
echo " [-v <Box Version, default: '$BOX_VERSION'>]"
echo ""
echo " This script requires Vagrant Cloud and an existing AWS MFA session."
echo " AWS session information should be specified in "
echo " \$AWS_ACCESS_KEY_ID, \$AWS_SECRET_ACCESS_KEY, and"
echo " \$AWS_SESSION_TOKEN environment variables."
echo " The credentials must have IAM privileges to use the"
echo " AWS VM Import/Export service on the provided VM Import S3 Bucket."
echo ""
echo " The Vagrant Cloud token may be provided via a JSON file with an"
echo " 'access_token' key (-t option) or the \$VAGRANT_CLOUD_TOKEN "
echo " environment variable."
exit 1
}
# If AWS credentials aren't passed in via environment variables, attempt
# to get them using the CLI tools.
if [ -z "$AWS_ACCESS_KEY_ID" -o -z "$AWS_SECRET_ACCESS_KEY" ]; then
if [ -x "$(which aws)" ]; then
AWS_ACCESS_KEY_ID="$(aws configure get aws_access_key_id || true)"
AWS_SECRET_ACCESS_KEY="$(aws configure get aws_secret_access_key || true)"
AWS_SESSION_TOKEN="$(aws configure get aws_session_token || true)"
fi
fi
if [ -z "$AWS_ACCESS_KEY_ID" ]; then
printf "Error: AWS_ACCESS_KEY_ID is undefined.\n\n"
USAGE=yes
fi
if [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
printf "Error: AWS_SECRET_ACCESS_KEY is undefined.\n\n"
USAGE=yes
fi
if [ -z "$AWS_SESSION_TOKEN" ]; then
printf "Error: AWS_SESSION_TOKEN is undefined.\n\n"
USAGE=yes
fi
# Retrieve the Vagrant Cloud token from a JSON file that has an 'access_token'
# key (e.g., it could be used as a `-var-file` Packer argument).
if [ -f "$VAGRANT_CLOUD_TOKEN_FILE" ]; then
VAGRANT_CLOUD_TOKEN="$(jq -M -r -s '(if .[0].access_token? then .[0].access_token else "" end)' "$VAGRANT_CLOUD_TOKEN_FILE")"
fi
if [ -z "$VAGRANT_CLOUD_TOKEN" ]; then
printf "Error: VAGRANT_CLOUD_TOKEN is undefined.\n\n"
USAGE=yes
fi
# Checking required arguments.
if [ -z "$BOX_NAME" ]; then
printf "Error: Box name not provided.\n\n"
USAGE=yes
fi
if [ -z "$VMIMPORT_BUCKET" ]; then
printf "Error: VM Import S3 Bucket not provided.\n\n"
USAGE=yes
fi
if [ "$USAGE" = "yes" ]; then
usage
fi
# Set up preset variables for release box we're creating.
case "$BOX_NAME" in
centos7-hoot)
AMI_DESCRIPTION="CentOS 7 Hootenanny v$BOX_VERSION"
AMI_DISK_SIZE=12288
MEMSIZE=4096
PROVISIONER=hoot
OS=centos
OS_RELEASE=7.9
;;
centos7-minimal)
AMI_DESCRIPTION="CentOS 7 Minimal v$BOX_VERSION"
OS=centos
OS_RELEASE=7.9
;;
bionic-minimal)
AMI_DESCRIPTION="Ubuntu 18.04 (bionic) Minimal v$BOX_VERSION"
OS=ubuntu
OS_RELEASE=bionic
;;
trusty-minimal)
AMI_DESCRIPTION="Ubuntu 14.04 (trusty) Minimal v$BOX_VERSION"
OS=ubuntu
OS_RELEASE=trusty
;;
*)
echo "Do not know how to create a release for $BOX_NAME."
exit 1
;;
esac
# Temporary directory for box-related files.
BOX_DIR="$(mktemp -d)"
# Create the box first on the Vagrant Cloud account.
curl \
--silent --show-error \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
--data "{ \"box\": { \"username\": \"$VAGRANT_CLOUD_USER\", \"name\": \"$BOX_NAME\", \"is_private\": false } }" \
--output "$BOX_DIR/box-create.json" \
https://app.vagrantup.com/api/v1/boxes
if [ -n "$(jq -M -r -s '(if .[0].name? then .[0].name else "" end)' "$BOX_DIR/box-create.json")" ]; then
echo "Created $VAGRANT_CLOUD_USER/$BOX_NAME on Vagrant Cloud."
fi
# Generate VirtualBox-provided Vagrant box.
OS=$OS OS_RELEASE=$OS_RELEASE POST_PROCESSOR=vagrant-cloud PROVISIONER=$PROVISIONER \
./build.sh \
-var "vm_name=$BOX_NAME" \
-var "box_tag=$VAGRANT_CLOUD_USER/$BOX_NAME" \
-var "box_version=$BOX_VERSION" \
-var 'headless=true' \
-var "memsize=$MEMSIZE" \
-var 'ssh_wait_timeout=90m' \
-var "access_token=$VAGRANT_CLOUD_TOKEN"
# Generate AWS-provided Vagrant box.
OS=$OS OS_RELEASE=$OS_RELEASE POST_PROCESSOR=amazon-import PROVISIONER=$PROVISIONER \
./build.sh \
-var "vm_name=$BOX_NAME" \
-var "ami_description=$AMI_DESCRIPTION" \
-var "box_version=$BOX_VERSION" \
-var "disk_size=$AMI_DISK_SIZE" \
-var 'headless=true' \
-var "memsize=$MEMSIZE" \
-var "region=$REGION" \
-var 'ssh_wait_timeout=90m' \
-var "s3_bucket_name=$VMIMPORT_BUCKET" \
-var "access_key=$AWS_ACCESS_KEY_ID" \
-var "secret_key=$AWS_SECRET_ACCESS_KEY" \
-var "token=$AWS_SESSION_TOKEN" | tee "$BOX_DIR/packer-build.log"
# Determine the AMI ID from the build log.
BOX_AMI="$(awk "{ if (\$1 ~ /^$REGION:/ ) print \$2 }" < "$BOX_DIR/packer-build.log")"
if [ -z "$BOX_AMI" ]; then
echo "Could not determine AMI from packer log: $BOX_DIR/packer-build.log"
exit 1
fi
# Manually create box tarball with correct metadata.json and Vagrantfile.
pushd "$BOX_DIR"
cat > metadata.json <<EOF
{
"provider": "aws"
}
EOF
cat > Vagrantfile <<EOF
Vagrant.configure('2') do |config|
config.vm.provider :aws do |aws|
aws.region_config '$REGION', ami: '$BOX_AMI'
end
end
EOF
tar -czf aws.box metadata.json Vagrantfile
popd
# The base URL for the releases. For reference, API instructions came from:
# https://www.vagrantup.com/docs/vagrant-cloud/api.html
VAGRANT_URL="https://vagrantcloud.com/api/v1/box/$VAGRANT_CLOUD_USER/$BOX_NAME/version/$BOX_VERSION"
# Create aws provider for the new box version.
curl \
--silent --show-error \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
--data '{ "provider": { "name": "aws" } }' \
"$VAGRANT_URL/providers"
# Get the upload path for the new aws-provided box.
UPLOAD_RESPONSE="$(curl --silent --show-error --header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" "$VAGRANT_URL/provider/aws/upload")"
UPLOAD_PATH="$(echo "$UPLOAD_RESPONSE" | jq -M -r -s '(if .[0].upload_path? then .[0].upload_path else "" end)')"
if [ -n "$UPLOAD_PATH" ]; then
# Upload the box and finalize the release.
curl \
--silent --show-error \
--request PUT \
--upload-file "$BOX_DIR/aws.box" \
"$UPLOAD_PATH"
curl \
--silent --show-error \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
--request PUT \
"$VAGRANT_URL/release"
# Clean up box directory.
rm -fr "$BOX_DIR"
# All done!
exit 0
else
# Something happened, keep temp files around.
echo "No upload path retrieved, examine log and files in $BOX_DIR."
exit 1
fi