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