diff options
Diffstat (limited to 'scripts/contrib')
-rwxr-xr-x | scripts/contrib/mkefidisk.sh | 464 |
1 files changed, 0 insertions, 464 deletions
diff --git a/scripts/contrib/mkefidisk.sh b/scripts/contrib/mkefidisk.sh deleted file mode 100755 index ac4ec9c7fb..0000000000 --- a/scripts/contrib/mkefidisk.sh +++ /dev/null | |||
@@ -1,464 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # Copyright (c) 2012, Intel Corporation. | ||
4 | # All rights reserved. | ||
5 | # | ||
6 | # This program is free software; you can redistribute it and/or modify | ||
7 | # it under the terms of the GNU General Public License as published by | ||
8 | # the Free Software Foundation; either version 2 of the License, or | ||
9 | # (at your option) any later version. | ||
10 | # | ||
11 | # This program is distributed in the hope that it will be useful, | ||
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
14 | # the GNU General Public License for more details. | ||
15 | # | ||
16 | # You should have received a copy of the GNU General Public License | ||
17 | # along with this program; if not, write to the Free Software | ||
18 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | # | ||
20 | |||
21 | LANG=C | ||
22 | |||
23 | echo | ||
24 | echo "WARNING: This script is deprecated and will be removed soon." | ||
25 | echo "Please consider using wic EFI images instead." | ||
26 | echo | ||
27 | |||
28 | # Set to 1 to enable additional output | ||
29 | DEBUG=0 | ||
30 | OUT="/dev/null" | ||
31 | |||
32 | # | ||
33 | # Defaults | ||
34 | # | ||
35 | # 20 Mb for the boot partition | ||
36 | BOOT_SIZE=20 | ||
37 | # 5% for swap | ||
38 | SWAP_RATIO=5 | ||
39 | |||
40 | # Cleanup after die() | ||
41 | cleanup() { | ||
42 | debug "Syncing and unmounting devices" | ||
43 | # Unmount anything we mounted | ||
44 | unmount $ROOTFS_MNT || error "Failed to unmount $ROOTFS_MNT" | ||
45 | unmount $BOOTFS_MNT || error "Failed to unmount $BOOTFS_MNT" | ||
46 | unmount $HDDIMG_ROOTFS_MNT || error "Failed to unmount $HDDIMG_ROOTFS_MNT" | ||
47 | unmount $HDDIMG_MNT || error "Failed to unmount $HDDIMG_MNT" | ||
48 | |||
49 | # Remove the TMPDIR | ||
50 | debug "Removing temporary files" | ||
51 | if [ -d "$TMPDIR" ]; then | ||
52 | rm -rf $TMPDIR || error "Failed to remove $TMPDIR" | ||
53 | fi | ||
54 | } | ||
55 | |||
56 | trap 'die "Signal Received, Aborting..."' HUP INT TERM | ||
57 | |||
58 | # Logging routines | ||
59 | WARNINGS=0 | ||
60 | ERRORS=0 | ||
61 | CLEAR="$(tput sgr0)" | ||
62 | INFO="$(tput bold)" | ||
63 | RED="$(tput setaf 1)$(tput bold)" | ||
64 | GREEN="$(tput setaf 2)$(tput bold)" | ||
65 | YELLOW="$(tput setaf 3)$(tput bold)" | ||
66 | info() { | ||
67 | echo "${INFO}$1${CLEAR}" | ||
68 | } | ||
69 | error() { | ||
70 | ERRORS=$((ERRORS+1)) | ||
71 | echo "${RED}$1${CLEAR}" | ||
72 | } | ||
73 | warn() { | ||
74 | WARNINGS=$((WARNINGS+1)) | ||
75 | echo "${YELLOW}$1${CLEAR}" | ||
76 | } | ||
77 | success() { | ||
78 | echo "${GREEN}$1${CLEAR}" | ||
79 | } | ||
80 | die() { | ||
81 | error "$1" | ||
82 | cleanup | ||
83 | exit 1 | ||
84 | } | ||
85 | debug() { | ||
86 | if [ $DEBUG -eq 1 ]; then | ||
87 | echo "$1" | ||
88 | fi | ||
89 | } | ||
90 | |||
91 | usage() { | ||
92 | echo "Usage: $(basename $0) [-v] DEVICE HDDIMG TARGET_DEVICE" | ||
93 | echo " -v: Verbose debug" | ||
94 | echo " DEVICE: The device to write the image to, e.g. /dev/sdh" | ||
95 | echo " HDDIMG: The hddimg file to generate the efi disk from" | ||
96 | echo " TARGET_DEVICE: The device the target will boot from, e.g. /dev/mmcblk0" | ||
97 | } | ||
98 | |||
99 | image_details() { | ||
100 | IMG=$1 | ||
101 | info "Image details" | ||
102 | echo " image: $(stat --printf '%N\n' $IMG)" | ||
103 | echo " size: $(stat -L --printf '%s bytes\n' $IMG)" | ||
104 | echo " modified: $(stat -L --printf '%y\n' $IMG)" | ||
105 | echo " type: $(file -L -b $IMG)" | ||
106 | echo "" | ||
107 | } | ||
108 | |||
109 | device_details() { | ||
110 | DEV=$1 | ||
111 | BLOCK_SIZE=512 | ||
112 | |||
113 | info "Device details" | ||
114 | echo " device: $DEVICE" | ||
115 | if [ -f "/sys/class/block/$DEV/device/vendor" ]; then | ||
116 | echo " vendor: $(cat /sys/class/block/$DEV/device/vendor)" | ||
117 | else | ||
118 | echo " vendor: UNKOWN" | ||
119 | fi | ||
120 | if [ -f "/sys/class/block/$DEV/device/model" ]; then | ||
121 | echo " model: $(cat /sys/class/block/$DEV/device/model)" | ||
122 | else | ||
123 | echo " model: UNKNOWN" | ||
124 | fi | ||
125 | if [ -f "/sys/class/block/$DEV/size" ]; then | ||
126 | echo " size: $(($(cat /sys/class/block/$DEV/size) * $BLOCK_SIZE)) bytes" | ||
127 | else | ||
128 | echo " size: UNKNOWN" | ||
129 | fi | ||
130 | echo "" | ||
131 | } | ||
132 | |||
133 | unmount_device() { | ||
134 | grep -q $DEVICE /proc/mounts | ||
135 | if [ $? -eq 0 ]; then | ||
136 | warn "$DEVICE listed in /proc/mounts, attempting to unmount" | ||
137 | umount $DEVICE* 2>/dev/null | ||
138 | return $? | ||
139 | fi | ||
140 | return 0 | ||
141 | } | ||
142 | |||
143 | unmount() { | ||
144 | if [ "$1" = "" ] ; then | ||
145 | return 0 | ||
146 | fi | ||
147 | grep -q $1 /proc/mounts | ||
148 | if [ $? -eq 0 ]; then | ||
149 | debug "Unmounting $1" | ||
150 | umount $1 | ||
151 | return $? | ||
152 | fi | ||
153 | return 0 | ||
154 | } | ||
155 | |||
156 | # | ||
157 | # Parse and validate arguments | ||
158 | # | ||
159 | if [ $# -lt 3 ] || [ $# -gt 4 ]; then | ||
160 | if [ $# -eq 1 ]; then | ||
161 | AVAILABLE_DISK=`lsblk | grep "disk" | cut -f 1 -d " "` | ||
162 | X=0 | ||
163 | for disk in `echo $AVAILABLE_DISK`; do | ||
164 | mounted=`lsblk /dev/$disk | awk {'print $7'} | sed "s/MOUNTPOINT//"` | ||
165 | if [ -z "$mounted" ]; then | ||
166 | UNMOUNTED_AVAILABLES="$UNMOUNTED_AVAILABLES /dev/$disk" | ||
167 | info "$X - /dev/$disk" | ||
168 | X=`expr $X + 1` | ||
169 | fi | ||
170 | done | ||
171 | if [ $X -eq 0 ]; then | ||
172 | die "No unmounted device found." | ||
173 | fi | ||
174 | read -p "Choose unmounted device number: " DISK_NUMBER | ||
175 | X=0 | ||
176 | for line in `echo $UNMOUNTED_AVAILABLES`; do | ||
177 | if [ $DISK_NUMBER -eq $X ]; then | ||
178 | DISK_TO_BE_FLASHED=$line | ||
179 | break | ||
180 | else | ||
181 | X=`expr $X + 1` | ||
182 | fi | ||
183 | done | ||
184 | if [ -z "$DISK_TO_BE_FLASHED" ]; then | ||
185 | die "Option \"$DISK_NUMBER\" is invalid. Choose a valid option" | ||
186 | else | ||
187 | if [ -z `echo $DISK_TO_BE_FLASHED | grep "mmc"` ]; then | ||
188 | TARGET_TO_BE_BOOT="/dev/sda" | ||
189 | else | ||
190 | TARGET_TO_BE_BOOT="/dev/mmcblk0" | ||
191 | fi | ||
192 | fi | ||
193 | echo "" | ||
194 | echo "Choose a name of the device that will be boot from" | ||
195 | echo -n "Recommended name is: " | ||
196 | info "$TARGET_TO_BE_BOOT" | ||
197 | read -p "Is target device okay? [y/N]: " RESPONSE | ||
198 | if [ "$RESPONSE" != "y" ]; then | ||
199 | read -p "Choose target device name: " TARGET_TO_BE_BOOT | ||
200 | fi | ||
201 | echo "" | ||
202 | if [ -z "$TARGET_TO_BE_BOOT" ]; then | ||
203 | die "Error: choose a valid target name" | ||
204 | fi | ||
205 | else | ||
206 | usage | ||
207 | exit 1 | ||
208 | fi | ||
209 | fi | ||
210 | |||
211 | if [ "$1" = "-v" ]; then | ||
212 | DEBUG=1 | ||
213 | OUT="1" | ||
214 | shift | ||
215 | fi | ||
216 | |||
217 | if [ -z "$AVAILABLE_DISK" ]; then | ||
218 | DEVICE=$1 | ||
219 | HDDIMG=$2 | ||
220 | TARGET_DEVICE=$3 | ||
221 | else | ||
222 | DEVICE=$DISK_TO_BE_FLASHED | ||
223 | HDDIMG=$1 | ||
224 | TARGET_DEVICE=$TARGET_TO_BE_BOOT | ||
225 | fi | ||
226 | |||
227 | LINK=$(readlink $DEVICE) | ||
228 | if [ $? -eq 0 ]; then | ||
229 | DEVICE="$LINK" | ||
230 | fi | ||
231 | |||
232 | if [ ! -w "$DEVICE" ]; then | ||
233 | usage | ||
234 | if [ ! -e "${DEVICE}" ] ; then | ||
235 | die "Device $DEVICE cannot be found" | ||
236 | else | ||
237 | die "Device $DEVICE is not writable (need to run under sudo?)" | ||
238 | fi | ||
239 | fi | ||
240 | |||
241 | if [ ! -e "$HDDIMG" ]; then | ||
242 | usage | ||
243 | die "HDDIMG $HDDIMG does not exist" | ||
244 | fi | ||
245 | |||
246 | # | ||
247 | # Ensure the hddimg is not mounted | ||
248 | # | ||
249 | unmount "$HDDIMG" || die "Failed to unmount $HDDIMG" | ||
250 | |||
251 | # | ||
252 | # Check if any $DEVICE partitions are mounted | ||
253 | # | ||
254 | unmount_device || die "Failed to unmount $DEVICE" | ||
255 | |||
256 | # | ||
257 | # Confirm device with user | ||
258 | # | ||
259 | image_details $HDDIMG | ||
260 | device_details $(basename $DEVICE) | ||
261 | echo -n "${INFO}Prepare EFI image on $DEVICE [y/N]?${CLEAR} " | ||
262 | read RESPONSE | ||
263 | if [ "$RESPONSE" != "y" ]; then | ||
264 | echo "Image creation aborted" | ||
265 | exit 0 | ||
266 | fi | ||
267 | |||
268 | |||
269 | # | ||
270 | # Prepare the temporary working space | ||
271 | # | ||
272 | TMPDIR=$(mktemp -d mkefidisk-XXX) || die "Failed to create temporary mounting directory." | ||
273 | HDDIMG_MNT=$TMPDIR/hddimg | ||
274 | HDDIMG_ROOTFS_MNT=$TMPDIR/hddimg_rootfs | ||
275 | ROOTFS_MNT=$TMPDIR/rootfs | ||
276 | BOOTFS_MNT=$TMPDIR/bootfs | ||
277 | mkdir $HDDIMG_MNT || die "Failed to create $HDDIMG_MNT" | ||
278 | mkdir $HDDIMG_ROOTFS_MNT || die "Failed to create $HDDIMG_ROOTFS_MNT" | ||
279 | mkdir $ROOTFS_MNT || die "Failed to create $ROOTFS_MNT" | ||
280 | mkdir $BOOTFS_MNT || die "Failed to create $BOOTFS_MNT" | ||
281 | |||
282 | |||
283 | # | ||
284 | # Partition $DEVICE | ||
285 | # | ||
286 | DEVICE_SIZE=$(parted -s $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//") | ||
287 | # If the device size is not reported there may not be a valid label | ||
288 | if [ "$DEVICE_SIZE" = "" ] ; then | ||
289 | parted -s $DEVICE mklabel msdos || die "Failed to create MSDOS partition table" | ||
290 | DEVICE_SIZE=$(parted -s $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//") | ||
291 | fi | ||
292 | SWAP_SIZE=$((DEVICE_SIZE*SWAP_RATIO/100)) | ||
293 | ROOTFS_SIZE=$((DEVICE_SIZE-BOOT_SIZE-SWAP_SIZE)) | ||
294 | ROOTFS_START=$((BOOT_SIZE)) | ||
295 | ROOTFS_END=$((ROOTFS_START+ROOTFS_SIZE)) | ||
296 | SWAP_START=$((ROOTFS_END)) | ||
297 | |||
298 | # MMC devices use a partition prefix character 'p' | ||
299 | PART_PREFIX="" | ||
300 | if [ ! "${DEVICE#/dev/mmcblk}" = "${DEVICE}" ] || [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then | ||
301 | PART_PREFIX="p" | ||
302 | fi | ||
303 | BOOTFS=$DEVICE${PART_PREFIX}1 | ||
304 | ROOTFS=$DEVICE${PART_PREFIX}2 | ||
305 | SWAP=$DEVICE${PART_PREFIX}3 | ||
306 | |||
307 | TARGET_PART_PREFIX="" | ||
308 | if [ ! "${TARGET_DEVICE#/dev/mmcblk}" = "${TARGET_DEVICE}" ]; then | ||
309 | TARGET_PART_PREFIX="p" | ||
310 | fi | ||
311 | TARGET_ROOTFS=$TARGET_DEVICE${TARGET_PART_PREFIX}2 | ||
312 | TARGET_SWAP=$TARGET_DEVICE${TARGET_PART_PREFIX}3 | ||
313 | |||
314 | echo "" | ||
315 | info "Boot partition size: $BOOT_SIZE MB ($BOOTFS)" | ||
316 | info "ROOTFS partition size: $ROOTFS_SIZE MB ($ROOTFS)" | ||
317 | info "Swap partition size: $SWAP_SIZE MB ($SWAP)" | ||
318 | echo "" | ||
319 | |||
320 | # Use MSDOS by default as GPT cannot be reliably distributed in disk image form | ||
321 | # as it requires the backup table to be on the last block of the device, which | ||
322 | # of course varies from device to device. | ||
323 | |||
324 | info "Partitioning installation media ($DEVICE)" | ||
325 | |||
326 | debug "Deleting partition table on $DEVICE" | ||
327 | dd if=/dev/zero of=$DEVICE bs=512 count=2 >$OUT 2>&1 || die "Failed to zero beginning of $DEVICE" | ||
328 | |||
329 | debug "Creating new partition table (MSDOS) on $DEVICE" | ||
330 | parted -s $DEVICE mklabel msdos >$OUT 2>&1 || die "Failed to create MSDOS partition table" | ||
331 | |||
332 | debug "Creating boot partition on $BOOTFS" | ||
333 | parted -s $DEVICE mkpart primary 0% $BOOT_SIZE >$OUT 2>&1 || die "Failed to create BOOT partition" | ||
334 | |||
335 | debug "Enabling boot flag on $BOOTFS" | ||
336 | parted -s $DEVICE set 1 boot on >$OUT 2>&1 || die "Failed to enable boot flag" | ||
337 | |||
338 | debug "Creating ROOTFS partition on $ROOTFS" | ||
339 | parted -s $DEVICE mkpart primary $ROOTFS_START $ROOTFS_END >$OUT 2>&1 || die "Failed to create ROOTFS partition" | ||
340 | |||
341 | debug "Creating swap partition on $SWAP" | ||
342 | parted -s $DEVICE mkpart primary $SWAP_START 100% >$OUT 2>&1 || die "Failed to create SWAP partition" | ||
343 | |||
344 | if [ $DEBUG -eq 1 ]; then | ||
345 | parted -s $DEVICE print | ||
346 | fi | ||
347 | |||
348 | |||
349 | # | ||
350 | # Check if any $DEVICE partitions are mounted after partitioning | ||
351 | # | ||
352 | unmount_device || die "Failed to unmount $DEVICE partitions" | ||
353 | |||
354 | |||
355 | # | ||
356 | # Format $DEVICE partitions | ||
357 | # | ||
358 | info "Formatting partitions" | ||
359 | debug "Formatting $BOOTFS as vfat" | ||
360 | if [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then | ||
361 | mkfs.vfat -I $BOOTFS -n "EFI" >$OUT 2>&1 || die "Failed to format $BOOTFS" | ||
362 | else | ||
363 | mkfs.vfat $BOOTFS -n "EFI" >$OUT 2>&1 || die "Failed to format $BOOTFS" | ||
364 | fi | ||
365 | |||
366 | debug "Formatting $ROOTFS as ext3" | ||
367 | mkfs.ext3 -F $ROOTFS -L "ROOT" >$OUT 2>&1 || die "Failed to format $ROOTFS" | ||
368 | |||
369 | debug "Formatting swap partition ($SWAP)" | ||
370 | mkswap $SWAP >$OUT 2>&1 || die "Failed to prepare swap" | ||
371 | |||
372 | |||
373 | # | ||
374 | # Installing to $DEVICE | ||
375 | # | ||
376 | debug "Mounting images and device in preparation for installation" | ||
377 | mount -o ro,loop $HDDIMG $HDDIMG_MNT >$OUT 2>&1 || error "Failed to mount $HDDIMG" | ||
378 | mount -o ro,loop $HDDIMG_MNT/rootfs.img $HDDIMG_ROOTFS_MNT >$OUT 2>&1 || error "Failed to mount rootfs.img" | ||
379 | mount $ROOTFS $ROOTFS_MNT >$OUT 2>&1 || error "Failed to mount $ROOTFS on $ROOTFS_MNT" | ||
380 | mount $BOOTFS $BOOTFS_MNT >$OUT 2>&1 || error "Failed to mount $BOOTFS on $BOOTFS_MNT" | ||
381 | |||
382 | info "Preparing boot partition" | ||
383 | EFIDIR="$BOOTFS_MNT/EFI/BOOT" | ||
384 | cp $HDDIMG_MNT/vmlinuz $BOOTFS_MNT >$OUT 2>&1 || error "Failed to copy vmlinuz" | ||
385 | # Copy the efi loader and configs (booti*.efi and grub.cfg if it exists) | ||
386 | cp -r $HDDIMG_MNT/EFI $BOOTFS_MNT >$OUT 2>&1 || error "Failed to copy EFI dir" | ||
387 | # Silently ignore a missing systemd-boot loader dir (we might just be a GRUB image) | ||
388 | cp -r $HDDIMG_MNT/loader $BOOTFS_MNT >$OUT 2>&1 | ||
389 | |||
390 | # Update the boot loaders configurations for an installed image | ||
391 | # Remove any existing root= kernel parameters and: | ||
392 | # o Add a root= parameter with the target rootfs | ||
393 | # o Specify ro so fsck can be run during boot | ||
394 | # o Specify rootwait in case the target media is an asyncronous block device | ||
395 | # such as MMC or USB disks | ||
396 | # o Specify "quiet" to minimize boot time when using slow serial consoles | ||
397 | |||
398 | # Look for a GRUB installation | ||
399 | GRUB_CFG="$EFIDIR/grub.cfg" | ||
400 | if [ -e "$GRUB_CFG" ]; then | ||
401 | info "Configuring GRUB" | ||
402 | # Delete the install entry | ||
403 | sed -i "/menuentry 'install'/,/^}/d" $GRUB_CFG | ||
404 | # Delete the initrd lines | ||
405 | sed -i "/initrd /d" $GRUB_CFG | ||
406 | # Delete any LABEL= strings | ||
407 | sed -i "s/ LABEL=[^ ]*/ /" $GRUB_CFG | ||
408 | |||
409 | sed -i "s@ root=[^ ]*@ @" $GRUB_CFG | ||
410 | sed -i "s@vmlinuz @vmlinuz root=$TARGET_ROOTFS ro rootwait console=ttyS0 console=tty0 @" $GRUB_CFG | ||
411 | fi | ||
412 | |||
413 | # Look for a systemd-boot installation | ||
414 | SYSTEMD_BOOT_ENTRIES="$BOOTFS_MNT/loader/entries" | ||
415 | SYSTEMD_BOOT_CFG="$SYSTEMD_BOOT_ENTRIES/boot.conf" | ||
416 | if [ -d "$SYSTEMD_BOOT_ENTRIES" ]; then | ||
417 | info "Configuring SystemD-boot" | ||
418 | # remove the install target if it exists | ||
419 | rm $SYSTEMD_BOOT_ENTRIES/install.conf >$OUT 2>&1 | ||
420 | |||
421 | if [ ! -e "$SYSTEMD_BOOT_CFG" ]; then | ||
422 | echo "ERROR: $SYSTEMD_BOOT_CFG not found" | ||
423 | fi | ||
424 | |||
425 | sed -i "/initrd /d" $SYSTEMD_BOOT_CFG | ||
426 | sed -i "s@ root=[^ ]*@ @" $SYSTEMD_BOOT_CFG | ||
427 | sed -i "s@options *LABEL=boot @options LABEL=Boot root=$TARGET_ROOTFS ro rootwait console=ttyS0 console=tty0 @" $SYSTEMD_BOOT_CFG | ||
428 | fi | ||
429 | |||
430 | # Ensure we have at least one EFI bootloader configured | ||
431 | if [ ! -e $GRUB_CFG ] && [ ! -e $SYSTEMD_BOOT_CFG ]; then | ||
432 | die "No EFI bootloader configuration found" | ||
433 | fi | ||
434 | |||
435 | |||
436 | info "Copying ROOTFS files (this may take a while)" | ||
437 | cp -a $HDDIMG_ROOTFS_MNT/* $ROOTFS_MNT >$OUT 2>&1 || die "Root FS copy failed" | ||
438 | |||
439 | echo "$TARGET_SWAP swap swap defaults 0 0" >> $ROOTFS_MNT/etc/fstab | ||
440 | |||
441 | # We dont want udev to mount our root device while we're booting... | ||
442 | if [ -d $ROOTFS_MNT/etc/udev/ ] ; then | ||
443 | echo "$TARGET_DEVICE" >> $ROOTFS_MNT/etc/udev/mount.blacklist | ||
444 | fi | ||
445 | |||
446 | # Add startup.nsh script for automated boot | ||
447 | printf "fs0:\%s\BOOT\%s\n" "EFI" "bootx64.efi" > $BOOTFS_MNT/startup.nsh | ||
448 | |||
449 | |||
450 | # Call cleanup to unmount devices and images and remove the TMPDIR | ||
451 | cleanup | ||
452 | |||
453 | echo "" | ||
454 | if [ $WARNINGS -ne 0 ] && [ $ERRORS -eq 0 ]; then | ||
455 | echo "${YELLOW}Installation completed with warnings${CLEAR}" | ||
456 | echo "${YELLOW}Warnings: $WARNINGS${CLEAR}" | ||
457 | elif [ $ERRORS -ne 0 ]; then | ||
458 | echo "${RED}Installation encountered errors${CLEAR}" | ||
459 | echo "${RED}Errors: $ERRORS${CLEAR}" | ||
460 | echo "${YELLOW}Warnings: $WARNINGS${CLEAR}" | ||
461 | else | ||
462 | success "Installation completed successfully" | ||
463 | fi | ||
464 | echo "" | ||