~philroche/ubuntu-on-ec2/ec2-publishing-scripts-cim-public

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

export LANG=C

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

Usage() {
	cat <<EOF
Usage: ${0##*/} [ options ] label build_dir

   Promote a daily build to a release

   label is like "daily", "alpha2", "beta1", "beta", "rc", "release"
   options:
      -p | --make-public    do not make build public
      -v | --verbose        be more verbose
           --allow-existing do not fail if items have been published
                            already (use if resuming a failed publish)
           --republish      **You probably do not want this**
                            run through all the steps on a published dir

   If '--make-public' is not given, then:
    - build directory will not be copied to the 'releases' dir
    - access will only be granted to those in 'private' group
    - query information will not be updated
    - subsequent run of same command with --make-public will do all the above

   The idea is to run this once like:
      ${0##*/} alpha3 /srv/ec2-images/server/lucid/20100224
   Then again later, at actual release time with:
      ${0##*/} --make-public alpha3 /srv/ec2-images/server/lucid/20100224
EOF
}

bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }

short_opts="hv"
long_opts="allow-existing,help,make-public,republish,verbose"
getopt_out=$(getopt --name "${0##*/}" \
	--options "${short_opts}" --long "${long_opts}" -- "$@") &&
	eval set -- "${getopt_out}" ||
	bad_Usage

make_public=0
publish_base=${PUBLISH_BASE:-/srv/ec2-images}
release_base="${publish_base}/releases"
verbosity=0
pthrough=( )
republish=0
allow_existing=""

while [ $# -ne 0 ]; do
	cur=${1}; next=${2};
	case "$cur" in
		   --make-public) make_public=1;;
		-v|--verbose)
			verbosity=$((${verbosity}+1))
			pthrough[${#pthrough[@]}]=${cur};;
		-h|--help) Usage; exit 0;;
		   --allow-existing) allow_existing="--allow-existing";;
		   --republish) republish=1; make_public=1;;
		--) shift; break;;
	esac
	shift;
done

[ $# -eq 2 ] || bad_Usage "must provide label and build_dir"
label=${1}
# if label is 'alpha-3', turn it to 'alpha3'
label=${label//-/}
build_d_in=${2}

build_d=$(cd "${build_d_in}" && pwd) ||
	fail "failed to cd ${build_d_in}"
build_d=${build_d%/unpacked}

# check that build_d looks reasonable
build_info="${build_d}/unpacked/build-info.txt"
[ -f "${build_info}" ] || fail "unable to find build-info at ${build_info}"

serial=""
suite=""
build_name=""

. "${build_info}" || fail "failed to source build-info ${build_info}"

for v in serial suite build_name; do
	[ -n "${!v}" ] || fail "$v not set in ${build_info}"
done

TEMP_D=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX")
trap cleanup EXIT

export XC2_XIMAGES_CACHE_D=${XC2_XIMAGES_CACHE_D:-"$TEMP_D/ximgcache"}

# change label to pr_status (publish-release label)
# publish-release wants "alpha-3", every where else these scripts use 'alpha3'
case "${label}" in
	alpha*) pr_status=alpha-${label#alpha};;
	beta) pr_status=beta;;
	beta*) pr_status=beta-${label#beta};;
	rc) pr_status=rc;;
	rc*) pr_status=rc-${label#rc};;
	release) pr_status=release;;
esac

symsrc=""
case "${label}" in
	release) 
		release_dir="${release_base}/${suite}/release-${serial}"
		symsrc="${release_base}/${suite}/release"
		[ -d "${symsrc}" -a ! -L "${symsrc}" ] &&
			fail "${symsrc} is a dir, please move it to ${symsrc}-<serial>"
		;;
	*) release_dir="${release_base}/${suite}/${pr_status}";;
esac

[ ! -d "${release_dir}" -o "$republish" -eq 1 ] ||
	fail "${release_dir} already exists"

# if there is no published-ec2-release.txt file in build_d, then publish build
published_results="${build_d}/published-ec2-release.txt"
if [ "$republish" -eq 1 -a -f "$published_results" ]; then
	mv "$published_results" "$published_results.orig"
fi

# Drop ebs-standard and ebs-io1 from publication for xenial and after
if [[ "${suite}" > "xenial" || "${suite}" == "xenial" ]] ; then
    export OVERRIDE_ITEMS_EBS="i386:ebs-ssd amd64:ebs-ssd"
    export OVERRIDE_ITEMS_HVM="amd64:hvm-ssd"
fi

if [ ! -f "${published_results}" ]; then
	# do not add any launch permissions, those are added later
	error "publishing build ${suite}/${build_name}/${label}/${serial}"

	[ ${verbosity} -ne 0 ] && verbose="--verbose" || verbose=""

	[ $republish -eq 1 ] && noindex=0 || noindex=1
	NO_WEB_INDICES=$noindex \
		publish-build --serial "${serial}" --add-launch none ${verbose} \
		${allow_existing} \
		"${suite}" "${build_name}" "${label}" "${build_d}" ||
	fail "failed to publish build"
else
	error "using existing ${published_results}"
fi

if [ $republish -eq 0 ]; then
	# mark this directory as to be saved (from remove-old-dailies)
	echo "$(date): ${label}" > "${build_d}/.save"
fi

if [ "${make_public}" -eq 1 ]; then
	# publish-release takes
	# DAILY-SOURCE DAILY-DATE TYPE OFFICIAL [STATUS]
	pr_type="${build_name}-cloudimg" # build_name is "server" or [later] "desktop"

	# label is "alpha1", "beta1", "release" ...
	case "${label}" in
		alpha*) pr_offic="no";;
		beta*|rc*|release) pr_offic="named";;
	esac

	# for a release, publish-release writes to
	# ${publish_base}/releases/${suite}/release
	# which we want to manage as a symlink
	{ [ -z "${symsrc}" -o ! -e "${symsrc}" ] || rm "${symsrc}"; } ||
		fail "failed to remove ${symsrc}"

	if [ $republish -eq 0 ]; then
		for pr_date in "${serial}" "${serial}/unpacked"; do
			DIST=${suite} for-project ubuntu publish-release \
				"${suite}" ${pr_date} "${pr_type}" "${pr_offic}" "${pr_status}" ||
			fail "failed to publish-release for ${pr_date}"
		done
		if [ -n "$symsrc" -a -e "${symsrc}" ]; then
			mv "${symsrc}" "${symsrc}-${serial}" ||
				fail "failed to move $symsrc to $symsrc-$serial"
		fi
	fi

	if [ -n "${symsrc}" ]; then
		# this only applies to releases, but we attempt to find the newest
		# release-* entry, to account for a republish managing the 'release'
		# entry right
        newest_rel=$(cd "${release_dir%/*}";
			export LANG=C
			for d in *; do
				[ "${d#release-}" != "${d}" ] || continue;
				[ "${d%.[0-9]}" = "$d" ] &&
					echo "$d.0 $d" || echo "$d $d";
			done | sort | awk '{ x=$2 }; END {print x}')
		[ -n "$newest_rel" ] || newest_rel="release-$serial"
		ln -s "${newest_rel}" "${symsrc}" ||
			fail "failed to symlink release-${serial} to ${symsrc}"
	fi

	[ -d "${release_dir}" ] ||
		fail "${release_dir} wasn't written as expected (not a dir)"
fi

# if this build is to be made public, then publicize it
# otherwise, only give access to "private" ids
if [ ${make_public} -eq 1 ]; then
	error "making build public"
	publicize-build "${pthrough[@]}" "${label}" "${release_dir}" ||
		fail "failed to publicize-build ${label} ${release_dir}"
	trigger-sync
    { [ -e "${build_d}/.save" ] && rm "${build_d}/.save"; } ||
	    error "Warning: failed to delete ${build_d}/.save"
	echo "published to ${build_d_in} as ${label} to ${release_dir}"
else
	error "giving access to 'private'"
	modify-access --add private "${published_results}" ||
		fail "failed to grant access"
	echo "pre-published to ${build_d_in} as ${label}"
fi

exit 0