~philroche/ubuntu-on-ec2/ec2-publishing-scripts-ena-clean

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
#!/bin/bash
# vi: ts=4 noexpandtab

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
		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} 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} 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 3 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 3 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