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
|
#!/bin/bash
# vi: ts=4 noexpandtab
VERBOSITY=0
error() { echo "$@" 1>&2; }
errorp() { printf "$@" 1>&2; }
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
failp() { [ $# -eq 0 ] || errorp "$@"; exit 1; }
debug() {
local level=${1}
shift;
[ "${level}" -gt "${VERBOSITY}" ] && return
echo "$(date): ${@}" 1>&2
}
cleanup() {
[ -z "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
}
#has_id(id,file)
# return 0 if id is in file in second tab delimited field. similar to 'grep'
# but specific check
has_id() {
awk '-F\t' '$1 == "IMAGE" && $2 == id { e=0; exit(0);};
END { exit(e); }' "id=${1}" e=1 "${2}"
}
# retry(max,sleeptime, cmd)
# retry cmd up to max times until it suceeds, sleeping sleeptime in between
retry() {
local max=$1 sleep=$2 i=0 ret=0;
shift 2 || { debug 1 "bad input to retry"; return 1; }
while :; do
i=$(($i+1))
"$@" ; ret=$?
[ $ret -eq 0 ] && break
[ $i -eq 1 ] && debug 1 "cmd failed [$i/$max]: $*" ||
debug 2 "cmd failed [$i/$max]: $*"
[ $i -lt $max ] || break
sleep "$sleep"
done
if [ $ret -eq 0 ]; then
[ $i -ne 1 ] && debug 1 "cmd passed [$i/$max]: $*"
return 0
fi
return $ret
}
Usage() {
cat <<EOF
Usage: ${0##*/} [ options ] publish-info.txt [ publish-info.txt [ ... ] ]
options:
-a | --add ent add launch perms for entity to each in publish-info
-r | --remove ent remove launch perms for entity to each in publish-info
publish-info has white-space delimited lines with
region id arch img_type path/name
example:
eu-west-1 aki-d25d76a6 i386 kernel my-kernels/my-kernel1.manifest.xml
arch, img_type, path are not required
EOF
}
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }
short_opts="a:hnr"
long_opts="add:,dry-run,help,remove:"
getopt_out=$(getopt --name "${0##*/}" \
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
eval set -- "${getopt_out}" ||
bad_Usage
fullzero=$(readlink -f "${0}")
GROUP_LIST_DIR=${MODIFY_ACCESS_GROUP_LIST_DIR:-${fullzero%/*}}
modargs=( )
dry_run=0
dry_echo=""
only_owner=1
while [ $# -ne 0 ]; do
cur=${1}; next=${2};
case "$cur" in
-a|--add|-r|--remove)
# if there is a file in GROUP_LIST_DIR named ids-<next>.txt
# it is assumed to be formated with 1 per line of <id> : <name>
# only <id> is used
listfile="${GROUP_LIST_DIR}/ids-${next}.txt"
if [ -f "${listfile}" ]; then
list=$(awk -F: '$1 !~ /^#/ { print $1 }' "${listfile}") &&
[ -n "${list}" ] || fail "failed to read ${listfile}"
list=${list//-/}
ids=( ${list} )
else
ids=( ${next//-/} )
fi
for id in "${ids[@]}"; do
modargs[${#modargs[@]}]=${cur}
modargs[${#modargs[@]}]=${id}
done
shift;;
-n|--dry-run) dry_run=1;;
-h|--help) Usage; exit 0;;
--) shift; break;;
-*) bad_Usage "confused by ${cur}";;
esac
shift;
done
[ $# -ge 1 ] || bad_Usage "must provide publish-info"
[ ${#modargs[@]} -ne 0 ] || bad_Usage "must provide perms to change"
for f in "${@}"; do
[ -f "${f}" ] || fail "${f}: not a file"
done
TEMP_D=$(mktemp -d "${TEMP_D:-/tmp}/${0##*/}.XXXXXX") ||
fail "failed to make tempdir"
trap cleanup EXIT
export XC2_XIMAGES_CACHE_D=${XC2_XIMAGES_CACHE_D:-"$TEMP_D/ximgcache"}
[ ${dry_run} -eq 0 ] || dry_echo="echo"
if [ ${only_owner} -eq 1 ]; then
rlist=$(awk '-F\t' '/^[^#]/ { print $1 }' "$@" | sort -u)
for region in ${rlist}; do
sfile="${TEMP_D}/${region}.self.list"
# get a list of images owned by self
retry 40 5 xc2 ximages describe-images --region "${region}" -o self > "${sfile}" ||
fail "failed to describe self-owned images in ${region}"
# get a list of image ids to operate on
ids=$(awk '-F\t' '$1 == r { print $2 }' "r=${region}" "$@") ||
fail "failed to get list of ids in ${region}"
owned=""
other=""
# find out which in list are owned, and which are not
# those owned will be in the self list output for this region
for id in ${ids}; do
has_id "${id}" "${sfile}" &&
owned="${owned} ${id}" ||
{ [[ "${id}" =~ ami ]] &&
owned="${owned} ${id}" ||
other="${other} ${id}"
}
done
other=${other# }
owned=${owned# }
[ -n "${other}" ] &&
error "skipping ids not owned in ${region}: ${other}"
[ -n "${owned}" ] ||
{ error "Warning: none of ids in ${region} were owned"; continue; }
for id in ${owned}; do
${dry_echo} retry 40 5 xc2 modify-image-attribute --region "${region}" \
--launch-permission "${modargs[@]}" ${id} ||
fail "failed to set perms for ${region}/${id}: ${modargs[*]}"
snap=$(xc2 ximages describe-images --region "${region}" "${id}" |
awk '$1 == "BLOCKDEVICEMAPPING" && $3 == "/dev/sda1" { print $4 }')
[ -z "${snap}" ] || {
${dry_echo} retry 40 5 xc2 modify-snapshot-attribute --region "${region}" \
--create-volume-permission "${modargs[@]}" "${snap}" ||
fail "failed to set snapshot perms for (${snap}): ${region}/${id}: ${modargs[*]}";
}
done
done
else
for f in "${@}"; do
while read region id arch img_type path; do
[ "${region#\#}" = "${region}" ] || continue # skip comment lines
printf "%s %s\n" "${region}" "${id}${path:+ ${path}}"
${dry_echo} retry 40 5 xc2 modify-image-attribute --region "${region}" \
--launch-permission "${modargs[@]}" "${id}" ||
fail "failed to set perms for ${region}/${id}: ${modargs[*]}"
snap=$(xc2 ximages describe-images --region "${region}" "${id}" |
awk '$1 == "BLOCKDEVICEMAPPING" && $3 == "/dev/sda1" { print $4 }')
[ -z "${snap}" ] || {
printf "%s %s %s\n" "${region}" "${snap}" "${id}${path:+ ${path}}"
${dry_echo} retry 40 5 xc2 modify-snapshot-attribute --region "${region}" \
--create-volume-permission "${modargs[@]}" "${snap}" ||
fail "failed to set snapshot perms for (${snap}): ${region}/${id}: ${modargs[*]}";
}
done < "${f}"
done
fi
|