]>
Commit | Line | Data |
---|---|---|
1 | #!/bin/bash | |
2 | ||
3 | # Constants | |
4 | ||
5 | # Proper error codes | |
6 | EXIT_OK=0 | |
7 | EXIT_ERROR=1 | |
8 | EXIT_CONF_ERROR=2 | |
9 | EXIT_NOT_SUPPORTED=3 | |
10 | EXIT_NOT_HANDLED=4 | |
11 | EXIT_COMMAND_NOT_FOUND=127 | |
12 | EXIT_ERROR_ASSERT=128 | |
13 | ||
14 | EXIT_TRUE=0 | |
15 | EXIT_FALSE=1 | |
16 | EXIT_UNKNOWN=2 | |
17 | ||
18 | TRUE=0 | |
19 | FALSE=1 | |
20 | ||
21 | IMAGE_RELEASE=${FALSE} | |
22 | ||
23 | # Functions | |
24 | ||
25 | log() { | |
26 | local level=${1} | |
27 | local message=${2} | |
28 | echo "[${level}] ${message}" | |
29 | } | |
30 | ||
31 | cmd() { | |
32 | local cmd=$@ | |
33 | local ret | |
34 | ||
35 | log DEBUG "Running command: ${cmd}" | |
36 | ||
37 | ${cmd} | |
38 | ret=$? | |
39 | ||
40 | case "${ret}" in | |
41 | ${EXIT_OK}) | |
42 | return ${EXIT_OK} | |
43 | ;; | |
44 | *) | |
45 | log DEBUG "Returned with code '${ret}'" | |
46 | return ${ret} | |
47 | ;; | |
48 | esac | |
49 | } | |
50 | ||
51 | ||
52 | cleanup_stage_1() { | |
53 | # Unmount image | |
54 | umount ${IMAGE_MOUNT_DIR} | |
55 | ||
56 | # Remove partition from the kernel table. | |
57 | partx -d ${outlo}p1 | |
58 | ||
59 | # Remove loopback device | |
60 | losetup -d ${outlo} | |
61 | ||
62 | ||
63 | ||
64 | # Cleanup Config file for the local repo | |
65 | if [ -f "${LOCAL_REPO_FILE}" ]; then | |
66 | rm -f "${LOCAL_REPO_FILE}" | |
67 | fi | |
68 | ||
69 | } | |
70 | ||
71 | cleanup_stage_2() { | |
72 | # Drop working dir | |
73 | if [ -d "${WORKING_DIR}" ]; then | |
74 | rm -dfR "${WORKING_DIR}" | |
75 | fi | |
76 | } | |
77 | ||
78 | cleanup() { | |
79 | cleanup_stage_1 | |
80 | cleanup_stage_2 | |
81 | } | |
82 | ||
83 | generate_image_filename() { | |
84 | local distro=${1} | |
85 | local version=${2} | |
86 | local arch=${3} | |
87 | ||
88 | echo "${distro}-${version}-${arch}" | |
89 | } | |
90 | ||
91 | check_for_pakfire() { | |
92 | local return_value=0 | |
93 | ||
94 | # TODO | |
95 | # Check that pakfire-server binary is available | |
96 | # Check that pakfire binary is available | |
97 | ||
98 | # Check that repo files are installed. (pakfire need to know which repos exist) | |
99 | local repo_dir="/etc/pakfire/repos" | |
100 | ||
101 | if [ ! -d "${repo_dir}" ]; then | |
102 | log ERROR "Could not find respository directory ${repo_dir}" | |
103 | return_value=1 | |
104 | fi | |
105 | ||
106 | return ${return_value} | |
107 | } | |
108 | ||
109 | compress_image() { | |
110 | local compression=${1} | |
111 | local image_file=${2} | |
112 | local level=${3} | |
113 | ||
114 | log debug "Compressing ${image_file} with ${compression}" | |
115 | ||
116 | case "${compression}" in | |
117 | "xz") | |
118 | # Check that the file does not exist yet | |
119 | if [ -f "${image_file}.xz" ]; then | |
120 | log ERROR "Failed to compress the image. The file already exists" | |
121 | return ${EXIT_ERROR} | |
122 | fi | |
123 | cmd xz "-${level}" "${image_file}" | |
124 | ;; | |
125 | "zip") | |
126 | # Check that the file does not exist yet | |
127 | if [ -f "${image_file}.zip" ]; then | |
128 | log ERROR "Failed to compress the image. The file already exists" | |
129 | return ${EXIT_ERROR} | |
130 | ||
131 | fi | |
132 | cmd zip "-${level}" "${image_file}.zip" "${image_file}" | |
133 | # Remove the file which we compressed+ | |
134 | rm -f "${image_file}" | |
135 | ;; | |
136 | ||
137 | esac | |
138 | } | |
139 | ||
140 | reset_root_password() { | |
141 | local root_dir=${1} | |
142 | # Backup passwd file | |
143 | cp -avf ${root_dir}/etc/passwd ${root_dir}/etc/passwd.orig | |
144 | ||
145 | # Drop root password. | |
146 | sed -e "s/^\(root:\)[^:]*:/\1:/" ${root_dir}/etc/passwd.orig > ${root_dir}/etc/passwd | |
147 | ||
148 | # Remove passwd backup file. | |
149 | rm -rvf ${root_dir}/etc/passwd.orig | |
150 | } | |
151 | ||
152 | clone_git_repos() { | |
153 | # Dir where the repos should be located | |
154 | local dir=${1} | |
155 | shift | |
156 | local repos="$@" | |
157 | ||
158 | local repo | |
159 | ||
160 | mkdir -pv ${dir} | |
161 | ||
162 | ( | |
163 | cd ${dir} | |
164 | # Clone git repositories. | |
165 | for repo in ${repos}; do | |
166 | git clone ${repo} | |
167 | done | |
168 | ) | |
169 | } | |
170 | ||
171 | # This function is used to publish the produced images | |
172 | ||
173 | publish() { | |
174 | local path=${1} | |
175 | # The image we created usually a img. file | |
176 | local image_base_file=${2} | |
177 | ||
178 | local image_name_final="$(generate_image_filename "${DISTRO}" "${VERSION}" "${ARCH}")" | |
179 | local image_type | |
180 | ||
181 | # Do these steps for every image format we like to publish | |
182 | for image_type in ${IMAGE_TYPES_PUBLISH}; do | |
183 | # Convert images to the type specified in IMAGE_TYPES_PUBLISH | |
184 | convert_image "${image_type}" "${image_base_file}" "${image_name_final}" | |
185 | ||
186 | # compress image. | |
187 | if [[ ${IMAGE_RELEASE} -eq ${TRUE} ]]; then | |
188 | local compression_type | |
189 | local compression_level | |
190 | ||
191 | ||
192 | # Get compressioon type | |
193 | compression_type="$(get_compression_type ${image_type})" | |
194 | ||
195 | compression_level=1 | |
196 | compress_image "${compression_type}" "${image_name_final}.${image_type}" ${compression_level} | |
197 | ||
198 | # Move images to this path | |
199 | mv -f "${image_name_final}.${image_type}.${compression_type}" ${path} | |
200 | ||
201 | # point the latest links to these images | |
202 | ln -s -f "${path}/${image_name_final}.${image_type}.${compression_type}" \ | |
203 | "${path}/$(generate_image_filename "${DISTRO}" "latest" "${ARCH}").${image_type}.${compression_type}" | |
204 | else | |
205 | ||
206 | # Move images to this path | |
207 | mv -f "${image_name_final}.${image_type}" ${path} | |
208 | fi | |
209 | done | |
210 | ||
211 | } | |
212 | ||
213 | convert_image() { | |
214 | local type=${1} | |
215 | local from=${2} | |
216 | local to=${3} | |
217 | ||
218 | if [[ ${type} = "img" ]]; then | |
219 | # We do not need to convert the image here but we need to rename | |
220 | mv -f ${from} ${to}.${type} | |
221 | return $? | |
222 | fi | |
223 | ||
224 | if [[ ${type} = "qcow2" ]]; then | |
225 | local command="qemu-img convert -c -O ${type} ${from} ${to}.${type}" | |
226 | else | |
227 | local command="qemu-img convert -O ${type} ${from} ${to}.${type}" | |
228 | fi | |
229 | ||
230 | cmd ${command} | |
231 | } | |
232 | ||
233 | get_compression_type() { | |
234 | local image_type=${1} | |
235 | ||
236 | case "${image_type}" in | |
237 | "qcow2" | "img") | |
238 | # These types can be used only under Unix so we use xz as compression | |
239 | echo "xz" | |
240 | ;; | |
241 | "vmdk" | "vdi") | |
242 | # These types can be also under Windows so we use zip as compression | |
243 | echo "zip" | |
244 | ;; | |
245 | esac | |
246 | ||
247 | } | |
248 | ||
249 | check_for_free_space() { | |
250 | local space=${1} | |
251 | local path=${2} | |
252 | local space_in_path=0 | |
253 | ||
254 | space_in_path=$(df -h -B MB --output=avail ${path} | tail -n 1) | |
255 | space_in_path=${space_in_path%MB} | |
256 | log debug ${space_in_path} | |
257 | log debug ${space} | |
258 | ||
259 | if [ ${space_in_path} -lt ${space} ]; then | |
260 | log error "Not enough free space available under ${path}" | |
261 | log error "Free space is ${space_in_path}MB but we need at least ${space}MB" | |
262 | return ${EXIT_ERROR} | |
263 | fi | |
264 | } | |
265 | ||
266 | parse_cmdline() { | |
267 | while [ $# -gt 0 ]; do | |
268 | case "${1}" in | |
269 | "--release") | |
270 | IMAGE_RELEASE=${TRUE} | |
271 | ;; | |
272 | ||
273 | *) | |
274 | error "Invalid argument: ${1}" | |
275 | return ${EXIT_CONF_ERROR} | |
276 | ;; | |
277 | esac | |
278 | shift | |
279 | done | |
280 | } | |
281 |