forked from dustinkirkland/bikeshed
-
Notifications
You must be signed in to change notification settings - Fork 2
/
cloud-sandbox
executable file
·219 lines (189 loc) · 6.03 KB
/
cloud-sandbox
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
#!/bin/bash
#
# cloud-sandbox - put and get binary files to/from pastebin.com
# Copyright (C) 2011 Dustin Kirkland <[email protected]>
#
# Authors: Dustin Kirkland <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
PKG=cloud-sandbox
mkdir -p "$HOME/.${PKG}"
[ -r "$HOME/.${PKG}/conf" ] && . "$HOME/.${PKG}/conf"
if [ -z "$EC2_KEYPAIR" ] || ! ec2-describe-keypairs "$EC2_KEYPAIR" >/dev/null 2>&1; then
echo "ERROR: You must define EC2_KEYPAIR to the path to your EC2 keypair pem file" 1>&2
echo "ERROR: You can do so in your environment or in [$HOME/.${PKG}/conf]" 1>&2
ec2-describe-keypairs
exit 1
fi
if [ -z "$LAUNCHPAD_ID" ]; then
echo "ERROR: You must define LAUNCHPAD_ID to your Launchpad.net user id" 1>&2
echo "ERROR: You can do so in your environment or in [$HOME/.${PKG}/conf]" 1>&2
exit 1
fi
if [ -z "$BOOTMAIL" ]; then
echo "ERROR: You must define BOOTMAIL to an email address" 1>&2
echo "ERROR: You can do so in your environment or in [$HOME/.${PKG}/conf]" 1>&2
exit 1
fi
if [ -z "$EC2_KEYPAIR_FILE" ]; then
#backsupport for default keypair file
EC2_KEYPAIR_FILE=$HOME/.ssh/ec2-keypair.pem
fi
EC2_KNOWN_HOSTS="$HOME/.ssh/known_hosts.cloud"
SSH_CMD="ssh -o UserKnownHostsFile=$EC2_KNOWN_HOSTS -i $EC2_KEYPAIR_FILE"
generate_ssh_host_keys() {
local d="$1"
local f=$(mktemp /tmp/cloud-user-data.XXXXXXXXXX)
printf "#cloud-config\nssh_keys:\n" >> "$f"
for i in rsa dsa; do
ssh-keygen -q -f "${d}/ssh_host_${i}_key" -t ${i} -N ""
printf " ${i}_private: |\n" >> "$f"
sed "s/^/ /" "${d}/ssh_host_${i}_key" >> "$f"
echo >> "$f"
printf " ${i}_public: " >> "$f"
cat "${d}/ssh_host_${i}_key.pub" >> "$f"
echo >> "$f"
done
_RET="$f"
}
add_known_hosts_entries() {
local i
local h="$1"
local ip="$2"
local d="$3"
for i in rsa dsa; do
printf "%s,%s %s %s\n" "$h" "$ip" $(awk '{print $1 " " $2}' "$d/ssh_host_${i}_key.pub") >> "$EC2_KNOWN_HOSTS"
done
#ssh-keygen -q -H -f "$EC2_KNOWN_HOSTS"
}
# Debugging, if I want to see what's going on
#set -x
# Optionally support release/size parameters
size="$1"
release="$2"
# Default to t1.micro/latest
[ -z "$size" ] && size="t1.micro"
if [ -z "$release" ]; then
command -v ubuntu-distro-info >/dev/null 2>&1 || { echo "FAIL: no ubuntu-distro-info."; exit 1; }
release=$(ubuntu-distro-info --devel 2>/dev/null)
if [ $? -ne 0 ]; then
echo "WARN: 'ubuntu-distro-info --devel' failed."
release=$(ubuntu-distro-info --all | tail -n 1) ||
{ echo "FAIL: failed to get latest distro"; exit 1; }
fi
fi
echo "release=$release"
# Generate the user-data file, and a first set of keys
d=$(mktemp -d /tmp/cloud.XXXXXXXXXX)
generate_ssh_host_keys "$d"
f="$_RET"
echo "
output: {all: '| tee -a /var/log/cloud-init-output.log'}
" >> $f
# Add Byobu
echo "
byobu_by_default: system
" >> $f
# SSH Import ID
if [ -n "$LAUNCHPAD_ID" ]; then
echo "
ssh_import_id: [$LAUNCHPAD_ID]
" >> $f
fi
# Add bootmail
if [ -n "$BOOTMAIL" ]; then
echo "
debconf_selections: |
debconf bootmail/recipients string $BOOTMAIL
packages:
bootmail
runcmd:
- sudo bootmail
" >> $f
fi
# Write random seed
SEED="$(head -c 512 /dev/urandom | base64 -w 0)"
echo "
write_files:
- encoding: b64
content: $SEED
owner: root:root
path: /dev/urandom
perms: '0666'
" >> $f
# Get the run command from the uec-images page
cmd="ubuntu-ec2-run -t $size --key $EC2_KEYPAIR --user-data-file $f $release"
id=$($cmd | grep "^INSTANCE" | awk '{print $2}')
rm -f "$f"
if [ -z "$id" ]; then
echo "ERROR: No instance id" 1>&2
exit 53
fi
# Loop until this instance is running
while ! (ec2-describe-instances $id | grep -qs running); do
sleep 5
done
# Now that it's running, get the hostname and ip
str=$(ec2-describe-instances $id | grep "^INSTANCE.*running")
h=$(echo "$str" | awk '{print $4}')
ip=$(echo "$str" | awk '{print $14}')
privip=$(echo "$str" | awk '{print $15}')
# Create --tag Name, sets the instance name
# Create --tag Created, sets a timestamp in a tag
created=$(date)
ec2-create-tags "$id" --tag Name="$LAUNCHPAD_ID" --tag Created="$created" --tag LaunchedBy="$PKG"
# Add the known_hosts entry
add_known_hosts_entries "$h" "$ip" "$d"
add_known_hosts_entries "$h" "$privip" "$d"
# Generate a second (secure) set of keys, since the first set was stored in EC2 metadata.
# Not a big deal, but local users would have had access to the private key.
d=$(mktemp -d /tmp/cloud.XXXXXXXXXX)
generate_ssh_host_keys "$d"
f="$_RET"
# Wait for SSH to come up
while ! $SSH_CMD ubuntu@$h true; do
sleep 1
true
done
# Securely install second set of keys to /etc/ssh
#tar -C "$d" -cf - . | $SSH_CMD ubuntu@$h "sudo tar -C /etc/ssh -xf -; sudo service ssh restart"
tar -C "$d" -cf - . | $SSH_CMD ubuntu@$h "sudo tar -C /etc/ssh -xf -"
ssh-keygen -q -f "$EC2_KNOWN_HOSTS" -R "$h"
ssh-keygen -q -f "$EC2_KNOWN_HOSTS" -R "$ip"
ssh-keygen -q -f "$EC2_KNOWN_HOSTS" -R "$privip"
add_known_hosts_entries "$h" "$ip" "$d"
add_known_hosts_entries "$h" "$privip" "$d"
rm -rf $d
# Now ssh in!
while ! $SSH_CMD ubuntu@$h; do
true
done
# Clean up?
echo -n "Do you want to terminate this instance now? [y/N]: "
answer=$(head -n1)
case "$answer" in
y|Y)
ec2-terminate-instances $id
ssh-keygen -f $EC2_KNOWN_HOSTS -R $h
ssh-keygen -f $EC2_KNOWN_HOSTS -R $ip
ssh-keygen -f $EC2_KNOWN_HOSTS -R $privip
rm -f "$EC2_KNOWN_HOSTS".old
;;
*)
echo "# Remember to clean up!"
echo " ec2-terminate-instances $id"
echo " ssh-keygen -f $EC2_KNOWN_HOSTS -R $h"
echo " ssh-keygen -f $EC2_KNOWN_HOSTS -R $ip"
echo " ssh-keygen -f $EC2_KNOWN_HOSTS -R $privip"
;;
esac