ovirt-node 2.2.0 release
[ovirt-node.git] / scripts / ovirt-functions
blob2c942224f5b3329c96c970870211dad9dc98741c
1 # -*-Shell-script-*-
3 OVIRT_LOGFILE=/var/log/ovirt.log
4 OVIRT_TMP_LOGFILE=/tmp/ovirt.log
5 touch $OVIRT_TMP_LOGFILE
6 chcon -t var_log_t $OVIRT_TMP_LOGFILE
7 _log_status=1
9 # label of the oVirt partition
10 OVIRT_LABEL=OVIRT
11 # configuration values are loaded in the following order:
12 # 1. /etc/sysconfig/node-config sets the default values
13 # 2. /etc/default/ovirt is loaded to override defaults with karg values
14 NODE_SYSCONFIG=/etc/sysconfig/node-config
15 OVIRT_DEFAULTS=/etc/default/ovirt
17 if [ -f "$NODE_SYSCONFIG" ]; then . "$NODE_SYSCONFIG"; fi
18 if [ -f $OVIRT_DEFAULTS ];   then . $OVIRT_DEFAULTS; fi
20 # fallback when default is empty
21 OVIRT_STANDALONE=${OVIRT_STANDALONE:-0}
23 OVIRT_BACKUP_DIR=/var/lib/ovirt-backup
25 MANAGEMENT_SCRIPTS_DIR=/etc/node.d
27 OVIRT_CONFIG_FILES="\
28  /etc/rsyslog.conf                              \
29  /etc/libvirt/libvirtd.conf                     \
30  /etc/libvirt/passwd.db                         \
31  /etc/passwd                                    \
32  /etc/shadow                                    \
33  /etc/ssh/ssh_host*_key*                        \
34  /etc/default/ovirt                             \
35  /etc/sysconfig/network                         \
36  /etc/collectd.conf                             \
37  /etc/logrotate.d/ovirt-node
40 . /usr/libexec/ovirt-boot-functions
41 LF=$'\n'
42 SEP=','
43 TAB=$'\t'
45 # Save stdout to fd 6 and stderr to fd 7.  Redirect normal stdout/stderr
46 # to log file
47 start_log() {
48     if [ "$_log_status" = 1 ]; then
49         exec 6>&1
50         exec 7>&2
51         exec 1>>$OVIRT_TMP_LOGFILE
52         exec 2>&1
53         _log_status=0
54     fi
57 # Restore stdout/stderr from fd 6 and 7, respectively.  Close fd 6 and 7
58 stop_log() {
59     if [ "$_log_status" != 1 ]; then
60         exec 1>&6 6>&-
61         exec 2>&7 7>&-
62         _log_status=1
63     fi
66 log() {
67     printf "$(date +'%b %d %H:%M:%S') "
69     if [ "$_log_status" = 1 ]; then
70         echo "$@"
71     else
72         echo "$@" >&6
73     fi
76 log_error() {
77     if [ "$_log_status" = 1 ]; then
78         echo "$@" >&2
79     else
80         printf "%s " "$(date +'%b %d %H:%M:%S')" "$@"
81         echo "$@" >&7
82     fi
85 ovirt_store_firstboot_config() {
86     # persist config for standalone
87     ovirt_store_config $OVIRT_CONFIG_FILES
90 # return 1 if oVirt Node is running in standalone mode
91 # return 0 if oVirt Node is managed by the oVirt Server
92 is_managed() {
93     return $OVIRT_STANDALONE
96 # oVirt Node in standalone mode does not try to contact the oVirt Server
97 is_standalone() {
98     if is_managed; then return 1; else return 0; fi
101 # return 0 if local storage is configured
102 # return 1 if local storage is not configured
103 is_local_storage_configured () {
104     if lvs HostVG/Config >/dev/null >&1; then
105         return 0
106     fi
108     return 1
111 # perform automatic local disk installation
112 # when at least following boot parameters are present:
113 # for networking - OVIRT_BOOTIF, management NIC
114 #       if other ip bootparams are not specified, IPv4 DHCP is assumed
115 # for storage - OVIRT_INIT, local disk to use
116 #       if ovirt_vol is not specified, default volume sizes are set
117 is_auto_install() {
118     if [ -n "$OVIRT_BOOTIF" ]; then
119         if [ -n "$OVIRT_INIT" ] ; then
120             return 0
121         elif egrep -q "storage_init|ovirt_init" /proc/cmdline ; then
122             return 2
123         else
124             return 1
125         fi
126     else
127         return 1
128     fi
131 # return 0 if this is an upgrade
132 # return 1 otherwise
133 is_upgrade() {
134     if [ "$OVIRT_UPGRADE" = "1" ]; then
135         return 0
136     else
137         return 1
138     fi
141 # return 0 if booted from local disk
142 # return 1 if booted from other media
143 is_booted_from_local_disk() {
144     grep -q LABEL=Root /proc/cmdline
147 # was firstboot menu already shown?
148 # state is stored in persistent config partition
149 is_firstboot() {
150     if [ -z "$OVIRT_FIRSTBOOT" -o "$OVIRT_FIRSTBOOT" = "1" ]; then
151         return 0
152     else
153         return 1
154     fi
157 # is install option passed?
158 is_install() {
159     if [ -z "$OVIRT_INSTALL" -o "$OVIRT_INSTALL" = "0" ]; then
160         return 1
161     else
162         return 0
163     fi
166 disable_firstboot() {
167     if mount_config; then
168         augtool <<EOF
169 set /files$OVIRT_DEFAULTS/OVIRT_FIRSTBOOT 0
170 set /files$OVIRT_DEFAULTS/OVIRT_INIT '""'
171 set /files$OVIRT_DEFAULTS/OVIRT_UPGRADE 0
173     fi
176 # Destroys a particular volume group and its logical volumes.
178 wipe_volume_group()
180     vg="$1"
181     local pv_dev=$2
183     for d in $(grep $vg /proc/mounts|awk '{print $2}'|sort -r); do
184         log "Unmounting $d"
185         umount $d
186     done
187     for d in $(grep $vg /proc/swaps|awk '{print $1}'); do
188         log "Turning off $d"
189         swapoff "$d"
190     done
191     log "Removing $vg"
192     if [ -z "$pv_dev" ]; then
193         LVM2_VG_NAME=""
194         LVM2_PV_NAME=""
195         pv_filter=""
196         pv_list=""
197         oldIFS="$IFS"
198         LF=$'\n'
199         IFS="$LF"
200         for vars in $(pvs --nameprefixes --noheadings -o pv_name,vg_name); do
201             eval  $vars
202             if [ "$LVM2_VG_NAME" = "HostVG" ]; then
203                 if [ -n "${pv_list}" ]; then
204                     pv_list="${pv_list}${LF}${LVM2_PV_NAME}"
205                     #pv_filter="${pv_filter}, \"a|^${LVM2_PV_NAME}\$|\""
206                 else
207                     pv_list="${LVM2_PV_NAME}"
208                     #pv_filter="${LVM2_PV_NAME}"
209                 fi
210             fi
211         done
212         yes | vgremove -f $vg
213         for pv in $pv_list; do
214             yes | pvremove -ff "$pv"
215         done
216         IFS="$oldIFS"
217     else
218         # XXX isn't filter is useless w/o "r|.*|" ?
219         yes | vgremove -f $vg --config " devices { filter = [ \"a|$pv_dev|\" ] } "
220         yes | pvremove -ff "$pv_dev" --config " devices { filter = [ \"a|$pv_dev|\" ] } "
221     fi
224 # find_srv SERVICE PROTO
226 # reads DNS SRV record
227 # sets SRV_HOST and SRV_PORT if DNS SRV record found, clears them if not
228 # Example usage:
229 # find_srv ovirt tcp
230 # if [ -n "$SRV_HOST" -a -n "$SRV_PORT" ]; then
231 #   echo "oVirt Server found"
232 # else
233 #   echo "no oVirt Server available, running standalone"
234 # fi
235 find_srv()
237     local dnsreply
238     local domain=$(dnsdomainname 2>/dev/null)
239     if [ "$domain" = "localdomain" ]; then
240         domain=""
241     fi
242     # FIXME dig +search does not seem to work with -t srv
243     # dnsreply=$(dig +short +search -t srv _$1._$2)
244     # This is workaround:
245     local search=$(grep search /etc/resolv.conf)
246     search=${search#search }
247     for d in $domain $search; do
248         dnsreply=$(dig +short -t srv _$1._$2.$d)
249         rc=$?
250         if [ $rc -eq 0 ]; then
251             set _ $dnsreply; shift
252             SRV_HOST=$4; SRV_PORT=$3
253             return 0
254         fi
255     done
256     SRV_HOST=; SRV_PORT=
257     return 1
260 die()
262     echo "$@" 1>&2; failure; echo 1>&2; exit 1
265 ovirt_setup_libvirtd() {
266     # just to get a boot warning to shut up
267     touch /etc/resolv.conf
269     # make libvirtd listen on the external interfaces
270     sed -i -e 's/^#\(LIBVIRTD_ARGS="--listen"\).*/\1/' \
271        /etc/sysconfig/libvirtd
273     # set up qemu daemon to allow outside VNC connections
274     sed -i -e 's/^[[:space:]]*#[[:space:]]*\(vnc_listen = "0.0.0.0"\).*/\1/' \
275        /etc/libvirt/qemu.conf
276     # set up libvirtd to listen on TCP (for kerberos)
277     sed -i -e "s/^[[:space:]]*#[[:space:]]*\(listen_tcp\)\>.*/\1 = 1/" \
278        -e "s/^[[:space:]]*#[[:space:]]*\(listen_tls\)\>.*/\1 = 0/" \
279        /etc/libvirt/libvirtd.conf
282 ovirt_setup_anyterm() {
283    # configure anyterm
284    cat >> /etc/sysconfig/anyterm << EOF
285 ANYTERM_CMD="sudo /usr/bin/virsh console %p"
286 ANYTERM_LOCAL_ONLY=false
289    # permit it to run the virsh console
290    echo "anyterm ALL=NOPASSWD: /usr/bin/virsh console *" >> /etc/sudoers
293 md5() {
294   md5sum $1 2>/dev/null | (read MD5 filename; echo $MD5)
297 # return uppercase value
298 uc() {
299     echo $(echo $1|tr '[[:lower:]]' '[[:upper:]]')
302 # return indirect value
303 # non-bashism for ${!var}
304 ptr() {
305     local v=$1
306     eval "v=\$$v"
307     echo $v
310 # mount livecd media
311 # e.g. CD /dev/sr0, USB /dev/sda1,
312 # PXE /dev/loop0 (loopback ISO)
313 # not available when booted from local disk installation
314 mount_live() {
315     if grep -q " /live " /etc/mtab; then
316         return 0
317     fi
318     local live_dev=/dev/live
319     if [ ! -e $live_dev ]; then
320         if losetup /dev/loop0|grep -q '\.iso'; then
321             # PXE boot
322             live_dev=/dev/loop0
323         else
324             return 1
325         fi
326     fi
327     mkdir -p /live
328     mount -r $live_dev /live || mount $live_dev /live
331 # mount root partition
332 # boot loader + kernel + initrd + LiveOS
333 mount_liveos() {
334     if grep -q " /liveos " /etc/mtab; then
335         return 0
336     fi
337     mkdir -p /liveos
338     mount LABEL=Root /liveos || mount -r LABEL=Root /liveos
341 mount_iscsi_liveos() {
342     if grep -q " /liveos " /etc/mtab; then
343         return 0
344     fi
345     mount LABEL=ovirt-node-root /liveos || mount -r LABEL=ovirt-node-root /liveos
347 # mount config partition
348 # /config for persistance
349 mount_config() {
350     # Only try to mount /config if the persistent storage exists
351     if [ -e /dev/HostVG/Config ] ; then
352         mkdir -p /config
353         if ! grep -q " /config ext[234] " /proc/mounts; then
354             mount /dev/HostVG/Config /config || return 1
355         fi
357         # optional config embedded in the livecd image
358         if [ -e /live/config ]; then
359             cp -rv --update /live/config/* /config
360         fi
361         # bind mount all persisted configs to rootfs
362         for f in $(find /config -type f); do
363             target=${f#/config}
364             if grep -q " $target ext[234]" /proc/mounts ; then
365                 # skip if already bind-mounted
366                 true
367             else
368                 mkdir -p "$(dirname $target)"
369                 touch "$target"
370                 mount -n --bind $f "$target"
371             fi
372         done
374         return 0
375     else
376         # /config is not available
377         return 1
378     fi
381 mount_boot() {
383     if grep -q " /boot " /etc/mtab; then
384        return 0
385     fi
386     mkdir -p /boot
387     mount LABEL=Boot /boot
389 # stop any service which keeps /var/log busy
390 # keep the list of services
391 unmount_logging_services() {
392     # mapping command->service is lame, but works for most initscripts
393     services=
394     cd /etc/init.d
395     # fixup for vdsm-reg intscript
396     if ! grep  "processname: vdsm-reg-setup" /etc/init.d/vdsm-reg; then
397         echo "# processname: vdsm-reg-setup" >> /etc/init.d/vdsm-reg
398     fi
399     for prg in $(lsof -Fc +D /var/log|grep ^c|sort -u); do
400         prog=${prg#c}
401         srv=$(grep -l "processname: .*$prog"$ *)
402         if [ -z "$srv" ]; then
403             # for scripts without chkconfig init header
404             srv=$(grep -l '^prog=["]*'$prog'["]*$' *)
405         fi
406         if [ -z "$srv" ]; then
407             # fallback for scripts without correct prog=
408             srv=$(grep -l '^DAEMON=["]*'$prog'["]*$' *)
409         fi
410         if [ -z "$srv" ]; then
411             # fallback for scripts with more than 1 daemon
412             srv=$(grep -l "daemon $prog$" *)
413         fi
414         if [ -n "$srv" ]; then
415             service $srv stop 6>&- 7>&-
416             services="$services $srv"
417         else
418             # failed to map process to initscript
419             killall "$prog"
420         fi
421     done
422     # debugging help
423     lsof +D /var/log
424     # unmount all under /var/log/
425     for d in $(grep /var/log/ /proc/mounts|awk '{print $2}'); do
426         log "Unmounting $d"
427         umount $d
428     done
431 # mount logging partition
432 # this only gets executed when disk is re-partitioned, HostVG/Logging is empty
433 mount_logging() {
434     if grep -q " /var/log ext[234]" /proc/mounts; then
435         return 0
436     fi
438     if [ -e /dev/HostVG/Logging ] ; then
439         log "Mounting log partition"
441         # temporary mount-point
442         log2=$(mktemp -d)
443         mkdir -p $log2
444         mount /dev/HostVG/Logging $log2
445         unmount_logging_services
446         # save logs from tmpfs
447         cp -av /var/log/* $log2
448         # save temporary log
449         if [ -e /tmp/ovirt.log ]; then
450             cp /tmp/ovirt.log $log2/ovirt.log-tmp
451         fi
452         mount --move $log2 /var/log
453         rmdir $log2
454         restorecon -rv /var/log
455         for srv in $services; do
456             service $srv start 6>&- 7>&-
457         done
459         return 0
460     else
461         # /var/log is not available
462         printf "\nThe logging partion has not been created. Please create it at the main menu.\n"
463         return 1
464     fi
467 unmount_logging() {
468     if ! grep -q " /var/log ext[234]" /proc/mounts; then
469         return 0
470     fi
472     log "Unmounting log partition"
473     # plymouthd keeps /var/log/boot.log
474     if plymouth --ping ; then
475         plymouth --quit
476     fi
477     unmount_logging_services
479     umount /var/log
480     rc=$?
481     if [ $rc -ne 0 ]; then
482         return $rc
483     fi
484     for srv in $services; do
485         service $srv start 6>&- 7>&-
486     done
488     return 0
491 # mount data partition
492 mount_data() {
493     udevadm settle
494     if [ -e /dev/HostVG/Data ] ; then
495         mkdir -p /data
496         if ! grep -q " /data ext[234]" /proc/mounts; then
497             mount /data
498         fi
500         mkdir -p /data/images
501         mkdir -p /data/images/rhev
502         chown 36:36 /data/images/rhev
503         mkdir -p /var/lib/libvirt/images
504         if ! grep -q "/var/lib/libvirt/images ext[234]" /proc/mounts; then
505             mount /var/lib/libvirt/images
506         fi
507         restorecon -rv /var/lib/libvirt/images
509         mkdir -p /data/core
510         mkdir -p /var/log/core
511         if ! grep -q "/var/log/core ext[234]" /proc/mounts; then
512             mount /var/log/core
513         fi
514         restorecon -rv /var/log/core
515         chmod 1777 /var/log/core
516         # configure kdump
517         cat > /etc/kdump.conf <<\EOF
518 default reboot
519 ext4 /dev/HostVG/Data
520 path /core
522         ovirt_store_config /etc/kdump.conf
523         service kdump restart
524         return 0
525     else
526         # /data is not available
527         printf "\nThe data partition has not been created. Create a Data partition with the \"Configure storage partitions\" menu.\n"
528         return 1
529     fi
532 mount_data2() {
533     if grep -q " /data2 ext3" /proc/mounts; then
534         return 0
535     fi
537     if [ -e /dev/AppVG/Data2 ] ; then
538         mkdir -p /data2
539         mount /data2
541         return 0
542     else
543         # /data2 is not available
544         printf "\nThe data2 partion has not been created. Please create it at the main menu.\n"
545         return 1
546     fi
549 mount_crypt_swap() {
550     crypttab="/etc/ovirt-crypttab"
551     if [ ! -s "${crypttab}" ]; then
552         return 1
553     fi
554     rc=0
556     while read label dev mapp cyph; do
557         if [ -n ${label} -a -n ${dev} -a -n ${mapp} -a -n ${cyph} ]; then
558             if grep -q "${dev}" /proc/swaps; then
559                 swapoff ${dev} >/dev/null 2>&1
560                 rc=$?
561                 [ ${rc} -ne 0 ] && {
562                     log "swapoff failed for Un-encrypted ${dev}";
563                     continue;
564                 }
565             fi
566             if [ ! -b ${mapp} ]; then
567                 /sbin/cryptsetup -d /dev/urandom -c ${cyph} create $(basename ${mapp}) ${dev} > /dev/null 2>&1
568                 rc=$?
569                 [ ${rc} -ne 0 ] && {
570                     log "Creation of encrypted swap for ${dev} failed";
571                     continue;
572                 }
573             fi
574             mkswap -L ${label} ${mapp} >/dev/null 2>&1
575             rc=$?
576             [ ${rc} -ne 0 ] && {
577                 log "Creation of swap for ${mapp} failed";
578                 continue;
579             }
580             swapon ${mapp} > /dev/null 2>&1
581             [ ${rc} -ne 0 ] && {
582                 log "Activation of swap for ${mapp} failed";
583                 continue;
584             }
585         else
586             continue
587         fi
588     done < ${crypttab}
590     return ${rc}
593 # augtool wrapper
594 #   workaround for bind-mounted files
595 #   see https://fedorahosted.org/augeas/ticket/32
596 # augtool [tmpaugscript]
597 # script MUST NOT include save, it is added by the wrapper
598 # with copy_if_rename_fails flag set
599 # 'tmpaugscript' is removed after successfull execution
600 # without a parameter, augtool commands are expected on standard input
601 augtool() {
602     local tmpaug=$1
603     if [ -z "$1" ]; then
604         # read from stdin
605         tmpaug=$(mktemp)
606         cat > $tmpaug
607     fi
608     cat >> $tmpaug <<EOF
609 clear /augeas/save/copy_if_rename_fails
610 save
612     /usr/bin/augtool < $tmpaug > /dev/null
613     rc=$?
614     if [ $rc -eq 0 ]; then
615         rm $tmpaug
616     fi
617     return $rc
620 # persist configuration to /config
621 #   ovirt_store_config /etc/config /etc/config2 ...
622 #   copy to /config and bind-mount back
623 ovirt_store_config() {
624     rc=0
625     if grep -q " /config ext[234]" /proc/mounts; then
626         for p in "$@"; do
627             local filename=$(readlink -f $p)
628             local persist_it=true
629             if [[ "$filename" =~ ^/[^/]*$ ]]; then
630                 # persisting top-level folder makes trouble rhbz#611617
631                 printf "Cannot persist system folder: ${filename}\n"
632                 persist_it=false
633             elif [ -d $filename ]; then
634                 if [ -d /config$filename ]; then
635                     printf "Directory already persisted: ${filename}\n"
636                     printf "You need to unpersist its child directories and/or files and try again.\n"
637                     persist_it=false
638                 fi
639             elif [ -f $filename ]; then
640                 if [ -f /config$filename ]; then
641                     local md5root=$(md5 $filename)
642                     local md5stored=$(md5 /config$filename)
643                     if [ "$md5root" = "$md5stored" ]; then
644                         printf "File already persisted: ${filename}\n"
645                         persist_it=false
646                     else
647                         # persistent copy needs refresh
648                         umount -n $filename 2> /dev/null || :
649                         rm -f /config$filename
650                     fi
651                 fi
652             else
653                 printf "Cannot persist: ${filename}\n"
654                 persist_it=false
655             fi
657             if $persist_it; then
658                 # skip if file does not exist
659                 if [ ! -e "${filename}" ]; then
660                     printf " Skipping, file '${filename}' does not exist\n"
661                     continue
662                 fi
663                 # skip if already bind-mounted
664                 if ! grep -q " $filename ext[234]" /proc/mounts ; then
665                     mkdir -p /config$(dirname $filename)
666                     cp -a $filename /config$filename \
667                         && mount -n --bind /config$filename $filename
668                     if [ $? -ne 0 ]; then
669                         printf " Failed to persist\n"
670                         rc=1
671                     else
672                         printf " File persisted\n"
673                     fi
674                 fi
675                 # register in /config/files used by rc.sysinit
676                 if ! grep -q "^${filename}$" /config/files 2> /dev/null ; then
677                     printf "${filename}\n" >> /config/files
678                 fi
679                 printf "\nSuccessfully persisted ${filename}\n"
680             fi
681         done
682         echo
683     else
684         printf "WARNING: persistent config storage not available\n"
685         rc=2
686     fi
687     return $rc
690 # check if stored config exists
691 #       is_persisted /etc/config
692 is_persisted() {
693     local abspath=$(readlink -e "$1")
694     test -f "/config$abspath"
697 # unmount bindmounted config files
698 #       unmount_config /etc/config /etc/config2 ...
700 # Use before running commands which fail on bindmounted files.
701 # After the file is replaced, call ovirt_store_config /etc/config ...
702 # to bindmount the config file again.
704 unmount_config() {
705     if grep -q " /config ext[234]" /proc/mounts; then
706         for p in "$@"; do
707             f=$(readlink -f $p)
708             if grep -q " $f ext[234]" /proc/mounts ; then
709                 if umount -n $f; then
710                     if [ -f /config$f ]; then
711                         # refresh the file in rootfs if it was mounted over
712                         cp -a /config$f $f
713                     fi
714                 fi
715             fi
716         done
717     fi
720 # remove persistent config files
721 #       remove_config /etc/config /etc/config2 ...
723 remove_config() {
724     # if there are no persisted files then just exit
725     if [ ! -s /config/files ]; then
726         printf "There are currently no persisted files.\n"
727         exit 1
728     fi
730     if grep -q " /config ext[234]" /proc/mounts; then
731         for p in "$@"; do
732             local filename=$(readlink -f $p)
733             if grep "^${filename}\$" /config/files > /dev/null 2>&1; then
734                 if grep -q " $filename ext[234]" /proc/mounts ; then
735                     if umount -n $filename; then
736                         if [ -d $filename ]; then
737                             cp -ar /config/$filename/* $filename
738                             if [ $? -ne 0 ]; then
739                                 printf " Failed to unpersist ${filename}\n"
740                                 exit 1
741                             else
742                                 printf " ${filename} successully unpersisted\n"
743                             fi
744                         else
745                             if [ -f /config$filename ]; then
746                                 # refresh the file in rootfs if it was mounted over
747                                 cp -a /config$filename $filename
748                                 if [ $? -ne 0 ]; then
749                                     printf " Failed to unpersist ${filename}\n"
750                                     exit 1
751                                 else
752                                     printf " ${filename} successully unpersisted\n"
753                                 fi
754                             fi
755                         fi
756                     fi
757                 else
758                     printf "$filename is not a persisted file.\n"
759                 fi
760                 # unregister in /config/files used by rc.sysinit
761                 sed --copy -i "\|^${filename}$|d" /config/files
762             else
763                 printf "File not explicitly persisted: ${filename}\n"
764             fi
765             # clean up the persistent store
766             rm -Rf /config$filename
767         done
768     fi
771 # ovirt_safe_delete_config
772 #       ovirt_safe_delete_config /etc/config /etc/config2 ...
774 # Use to *permanently* remove persisted configuration file.
775 # WARNING: file is shredded and removed
777 ovirt_safe_delete_config() {
778     local target
780     for target in "$@"; do
781         if grep -q " $target ext[234]" /proc/mounts; then
782             umount -n $target
783         fi
785         sed --copy -i "\|$target$|d" /config/files
787         if [ -d $target ]; then
788             for child in $(ls -d $target/*); do
789                 ovirt_safe_delete_config $child
790             done
791             rm -rf /config$target
792             rm -rf $target
793         else
794             shred -u /config$target
795             shred -u $target
796         fi
797     done
801 backup_file() {
802     dir=$(dirname "$1")
803     case $dir in /*);; *) die "unexpected non-absolute dir: $dir";; esac
804     mkdir -p "$OVIRT_BACKUP_DIR/${dir:1}"
805     test -f "$1" && cp -pf "$1" "$OVIRT_BACKUP_DIR/${dir:1}"
808 add_if_not_exist() {
809     string="$1"
810     file="$2"
812     grep -qE "^[[:space:]]*$string($|#|[[:space:]])" "$file" \
813         || echo "$string" >> "$file"
816 # $1 - the string to be trimmed
817 trim_whitespace () {
818     local text=${1}
820     printf "$text" | awk '{gsub(/^[ ]*/,"",$0); gsub(/[ ]*$/,"",$0) ; print }'
823 is_numeric() {
824     printf "$1" | grep -q -E '^[0-9]+$'
827 # LVM2 tools wrapper
828 # to avoid warnings like:
829 # File descriptor 6 (pipe:[20637]) leaked on lvrename invocation.
830 # File descriptor 7 (pipe:[20637]) leaked on lvrename invocation.
831 lvrename() {
832     /sbin/lvrename "$@" 6>&- 7>&-
835 pvs() {
836     /sbin/pvs "$@" 6>&- 7>&-
839 pvcreate() {
840     /sbin/pvcreate "$@" 6>&- 7>&-
843 pvremove() {
844     /sbin/pvremove "$@" 6>&- 7>&-
847 vgcreate() {
848     /sbin/vgcreate "$@" 6>&- 7>&-
851 vgremove() {
852     /sbin/vgremove "$@" 6>&- 7>&-
855 lvcreate() {
856     /sbin/lvcreate "$@" 6>&- 7>&-
859 lvremove() {
860     /sbin/lvremove "$@" 6>&- 7>&-
863 findfs() {
864     partprobe /dev/mapper/* 2>/dev/null
865     udevadm settle
866     /sbin/blkid -c /dev/null -l -o device -t "$@"
869 # reboot wrapper
870 #   cleanup before reboot
871 reboot() {
872     cd /
873     rc=0
874     if [ "$OVIRT_ISCSI_ENABLED" != "y" ]; then
875         # setup new Root if update is prepared
876         root_update_dev="$(findfs LABEL=RootUpdate 2>/dev/null)"
877         if [ -n "$root_update_dev" ]; then
878             set -x
879             root_dev="$(findfs LABEL=Root 2>/dev/null)"
880             e2label "$root_dev" RootBackup || rc=1
881             e2label "$root_update_dev" Root || rc=1
882             set +x
883         fi
884     fi
885     if [ $rc -ne 0 ]; then
886         log "Relabeling failed, please check logs"
887         return 1
888     fi
889     # run post-install hooks
890     # e.g. to avoid reboot loops using Cobbler PXE only once
891     # Cobbler XMLRPC post-install trigger (XXX is there cobbler SRV record?):
892     # wget "http://192.168.50.2/cblr/svc/op/trig/mode/post/system/$(hostname)"
893     #   -O /dev/null
894     for hook in $(ls /etc/ovirt-config-boot.d/* 2>/dev/null); do
895         $hook
896         rc=$?
897         if [ $? -ne 0 ]; then
898             log "Hook \"$hook\" failed."
899         fi
900     done
901     /sbin/reboot
904 # chkconfig_persist <servicename>
905 #   since symlinks cannot be persisted, replace symlinks with hardlinks and persist
906 chkconfig_persist() {
907     local service=$1
908     if [ -z "$service" ]; then
909         return 1
910     fi
911     cd /etc/rc.d
912     local to_persist=""
913     for f in rc*.d/[S,K]??$service ; do
914         local dir=$(dirname $f)
915         local name=$(basename $f)
916         cd $dir
917         link=$(readlink $name)
918         if [ -e "$link" ]; then
919             rm -f $name
920             ln $link $name
921             to_persist="$to_persist /etc/rc.d/$f"
922         fi
923         cd ..
924     done
925     ovirt_store_config $to_persist
928 # Asks a yes or no question. Accepts Y/N/A so users can abort.
929 # RC=0 - Y/y entered
930 # RC=1 - N/n entered
931 # RC=2 - A/a entered
932 # $1 - the prompt to use
933 # $2 - require a response (def. true)
934 # $3 - allow aborting (def. false)
935 ask_yes_or_no () {
936     local prompt=${1}
937     local required=${2-true}
938     local allow_abort=${3-false}
940     while true; do
941         read -ep "${prompt} "
942         case $REPLY in
943             Y|y) return 0;;
944             N|n) return 1;;
945             A|a) if $allow_abort; then return 2; fi ;;
946             *)
947                 if [ $required == false ]; then
948                     return 99
949                 fi
950                 ;;
951         esac
952     done
955 # Verifies the address entered is a valid IPv4 address.
956 is_valid_ipv4 () {
957     local address=${1}
958     local result=1
960     if [[ "$address" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
961         oldIFS="$IFS"
962         IFS='.'
963         ip=($address)
964         IFS="$oldIFS"
965         [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
966             && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
967         result=$?
968     fi
970     return $result
973 # Check if networking is already up
974 network_up () {
975     ip addr show | grep -q "inet.*scope global"
978 # wipe mbr from disks
979 wipe_mbr () {
980     local drive="$1"
981     log "Wiping old boot sector"
982     dd if=/dev/zero of="$drive" bs=1024K count=1
983     # zero out the GPT secondary header
984     log "Wiping secondary gpt header"
985     local disk_kb_count=$(sfdisk -s "$drive" 2>/dev/null)
986     dd if=/dev/zero of="$drive" bs=1024 seek=$(($disk_kb_count - 1)) count=1
987     kpartx -d "$drive"
990 # Cleans partition tables
991 wipe_partitions() {
992     local drive="$1"
993     wipe_mbr "$drive"
994     # disable HostVG/Swap before removing from dmtable
995     if [ -L /dev/mapper/HostVG-Swap ]; then
996         swapoff -a
997     fi
998     # remove remaining HostVG entries from dmtable
999     for lv in $(find /dev/mapper/HostVG*); do
1000         dmsetup remove $lv
1001     done
1004 test_ntp_configuration () {
1005     # stop ntpd service for testing
1006     service ntpd stop > /dev/null 2>&1
1007     SERVERS=$(echo $NTPSERVERS | awk 'BEGIN{FS=":"}{for (i=1; i<=NF; i++) print $i}')
1008         for server in $SERVERS; do
1009             ntpdate $server > /dev/null 2>&1
1010             result=$?
1011             if [ $result -ne 0 ]; then
1012                 printf "\n Unable to verify NTP server: $server \n"
1013             else
1014                 printf "\n Verified NTP server: $server \n"
1015             fi
1016         done
1017     service ntpd start
1021 get_dm_device ()
1023     local device="$1"
1024     major=$(stat -c '%t' "$(readlink -f "$device")")
1025     minor=$(stat -c '%T' "$(readlink -f "$device")")
1026     local dm_device=
1027     local rc=1
1028     oldIFS="$IFS"
1029     IFS=$'\n'
1030     for dm in /dev/mapper/*; do
1031         if [ $major = $(stat -c '%t' "$(readlink -f "$dm")") -a \
1032             $minor = $(stat -c '%T' "$(readlink -f "$dm")") ]; then
1033             dm_device="$dm"
1034             rc=0
1035             break
1036         fi
1037     done
1038     IFS="$oldIFS"
1039     echo "$dm_device"
1041     return $rc
1044 #Function to determine partition and device names
1045 get_part_info() {
1046     local drive_in="$1"
1047     local dev_var=$2
1048     local part_var=$3
1049     local grub_dev=$4
1050     local devname_1 devname2 part_number
1051     local rc=0
1053     if [ -z "$grub_dev" ]; then
1054         eval "$(readlink -f "$drive_in" | awk '{
1055             print "devname_1=\"" substr($0,1,length($0)-1) "\"";
1056             print "devname_2=\"" substr($0,1,length($0)-2) "\"";
1057             part_number=substr($0,length($0),1);
1058             print "part_number=" part_number;
1059         }')"
1060     else
1061         eval "$(readlink -f "$drive_in" | awk '{
1062             print "devname_1=\"" substr($0,1,length($0)-1) "\"";
1063             print "devname_2=\"" substr($0,1,length($0)-2) "\"";
1064             part_number=substr($0,length($0),1); part_number--;
1065             print "part_number=" part_number;
1066         }')"
1067     fi
1068     rc=$?
1070     if [ "$part_number" -lt 1 -a "$grub_dev" != "y" ]; then
1071         log "Partition number was invalid"
1072         return 2
1073     fi
1075     if [ -e "$devname_1" ]; then
1076         eval "$dev_var=\"$devname_1\""
1077     elif [ -e "$devname_2" ]; then
1078         eval "$dev_var=\"$devname_2\""
1079     else
1080         return 1
1081     fi
1082     eval "$part_var=$part_number"
1083     return $rc
1086 log_only() {
1087     echo "$@" >> $OVIRT_TMP_LOGFILE
1090 autoinstall_failed(){
1091     plymouth --hide-splash
1092     log "Automatic installation failed. Please review console messages."
1093     log "Press Enter to drop to emergency shell."
1094     read < /dev/console
1095     bash < /dev/console > /dev/console 2> /dev/console
1096     plymouth --show-splash
1099 get_base_device() {
1100     dev=$1
1101     if [ -e "${dev%?}" ]; then
1102         echo "${dev%?}"
1103         return 0
1104     elif [ -e "${dev%p?}" ]; then
1105         echo "${dev%p?}"
1106         return 0
1107     else
1108         return 1
1109     fi
1112 get_boot_device() {
1113     ROOT=$(get_base_device $(findfs LABEL=Root))
1114     ROOTBACKUP=$(get_base_device $(findfs LABEL=RootBackup))
1115     if [ "$ROOT" = "$ROOTBACKUP" ]; then
1116         echo "$ROOT"
1117         return 0
1118     else
1119         return 1
1120     fi
1123 # execute a function if called as a script, e.g.
1124 #   ovirt-functions ovirt_store_config /etc/hosts
1126 if [ "$(basename -- "$0")" = "ovirt-functions" ]; then
1127     "$@"