Statistics
| Branch: | Revision:

root / common.sh.in @ d4d9f7c9

History | View | Annotate | Download (8.9 kB)

1
#
2

    
3
# Copyright (C) 2007, 2008, 2009 Google Inc.
4
#
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
# General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
# 02110-1301, USA.
19

    
20
AWK="awk"
21
MKDIR_P="mkdir -p"
22
DUMP="dump"
23
RESTORE="restore"
24
LOSETUP="losetup"
25
KPARTX="kpartx"
26
SFDISK="sfdisk"
27
RESIZE2FS="resize2fs"
28
QEMU_IMG="qemu-img"
29
NTFSCLONE="ntfsclone"
30
XMLSTARLET="xmlstarlet"
31
INSTALL_MBR="install-mbr"
32
PROGRESS_MONITOR="snf-progress-monitor"
33

    
34
windows_support="@windows_support@"
35
progress_monitor_support="@progress_monitor_support@"
36

    
37
CLEANUP=( )
38

    
39
log_error() {
40
  echo "$@" >&2
41
}
42

    
43
debug() {
44
    [ "$IMAGE_DEBUG" == "1" -o "$IMAGE_DEBUG" == "yes" ] &&  $@ || :
45
}
46

    
47
get_api5_arguments() {
48
  GETOPT_RESULT=$*
49
  # Note the quotes around `$TEMP': they are essential!
50
  eval set -- "$GETOPT_RESULT"
51
  while true; do
52
    case "$1" in
53
      -i|-n) instance=$2; shift 2;;
54

    
55
      -o) old_name=$2; shift 2;;
56

    
57
      -b) blockdev=$2; shift 2;;
58

    
59
      -s) swapdev=$2; shift 2;;
60

    
61
      --) shift; break;;
62

    
63
      *)  log_error "Internal error!" >&2; exit 1;;
64
    esac
65
  done
66
  if [ -z "$instance" -o -z "$blockdev" ]; then
67
    log_error "Missing OS API Argument (-i, -n, or -b)"
68
    exit 1
69
  fi
70
  if [ "$SCRIPT_NAME" != "export" -a -z "$swapdev"  ]; then
71
    log_error "Missing OS API Argument -s (swapdev)"
72
    exit 1
73
  fi
74
  if [ "$SCRIPT_NAME" = "rename" -a -z "$old_name"  ]; then
75
    log_error "Missing OS API Argument -o (old_name)"
76
    exit 1
77
  fi
78
}
79

    
80
get_api10_arguments() {
81
  if [ -z "$INSTANCE_NAME" -o -z "$HYPERVISOR" -o -z "$DISK_COUNT" ]; then
82
    log_error "Missing OS API Variable:"
83
    log_error "(INSTANCE_NAME HYPERVISOR or DISK_COUNT)"
84
    exit 1
85
  fi
86
  instance=$INSTANCE_NAME
87
  if [ $DISK_COUNT -lt 1 -o -z "$DISK_0_PATH" ]; then
88
    log_error "At least one disk is needed"
89
    exit 1
90
  fi
91
  if [ "$SCRIPT_NAME" = "export" ]; then
92
    if [ -z "$EXPORT_DEVICE" ]; then
93
      log_error "Missing OS API Variable EXPORT_DEVICE"
94
    fi
95
    blockdev=$EXPORT_DEVICE
96
  elif [ "$SCRIPT_NAME" = "import" ]; then
97
    if [ -z "$IMPORT_DEVICE" ]; then
98
       log_error "Missing OS API Variable IMPORT_DEVICE"
99
    fi
100
    blockdev=$IMPORT_DEVICE
101
  else
102
    blockdev=$DISK_0_PATH
103
  fi
104
  if [ "$SCRIPT_NAME" = "rename" -a -z "$OLD_INSTANCE_NAME" ]; then
105
    log_error "Missing OS API Variable OLD_INSTANCE_NAME"
106
  fi
107
  old_name=$OLD_INSTANCE_NAME
108
}
109

    
110
get_api20_parameters() {
111
  if [ -z "$OSP_IMG_ID" -o -z "$OSP_IMG_FORMAT" -o -z "$OSP_IMG_PASSWD" ]; then
112
    log_error "Missing OS API Parameter:"
113
    log_error "(OSP_IMG_ID or OSP_IMG_FORMAT or OSP_IMG_PASSWD)"
114
    exit 1
115
  fi
116
  IMG_ID=$OSP_IMG_ID
117
  IMG_FORMAT=$OSP_IMG_FORMAT
118
  IMG_PASSWD=$OSP_IMG_PASSWD
119
}
120

    
121
mount_disk0() {
122
    local target=$1
123
    mount $root_dev $target
124
    CLEANUP+=("umount $target")
125
    if [ -n "${boot_dev}" ] ; then
126
        $MKDIR_P $target/boot
127
        mount $boot_dev $target/boot
128
        CLEANUP+=("umount $target/boot")
129
    fi
130
    # sync the file systems before unmounting to ensure everything is flushed
131
    # out
132
    CLEANUP+=("sync")
133
}
134

    
135
map_disk0() {
136
    blockdev="$1"
137
    filesystem_dev_base=`$KPARTX -l -p- $blockdev | \
138
                            grep -m 1 -- "-1.*$blockdev" | \
139
                            $AWK '{print $1}'`
140
    if [ -z "$filesystem_dev_base" ]; then
141
        log_error "Cannot interpret kpartx output and get partition mapping"
142
        exit 1
143
    fi
144
    $KPARTX -a -p- $blockdev > /dev/null
145
    filesystem_dev="/dev/mapper/${filesystem_dev_base/%-1/}"
146
    if [ ! -b "/dev/mapper/$filesystem_dev_base" ]; then
147
        log_error "Can't find kpartx mapped partition: /dev/mapper/$filesystem_dev_base"
148
        exit 1
149
    fi
150
    echo "$filesystem_dev"
151
}
152

    
153
map_partition() {
154
    filesystem_dev="$1"
155
    partition="$2"
156
    if [ "${SWAP}" = "yes" -a "${BOOT}" = "yes" ] ; then
157
        boot_dev="${filesystem_dev}-1"
158
        swap_dev="${filesystem_dev}-2"
159
        root_dev="${filesystem_dev}-3"
160
    elif [ "${SWAP}" = "no" -a "${BOOT}" = "yes" ] ; then
161
        boot_dev="${filesystem_dev}-1"
162
        root_dev="${filesystem_dev}-2"
163
    elif [ "${SWAP}" = "yes" -a "${BOOT}" = "no" ] ; then
164
        swap_dev="${filesystem_dev}-1"
165
        root_dev="${filesystem_dev}-2"
166
    elif [ "${SWAP}" = "no" -a "${BOOT}" = "no" ] ; then
167
        root_dev="${filesystem_dev}-1"
168
    fi
169
    echo "$(eval "echo \${$(echo ${partition}_dev)"})"
170
}
171

    
172
unmap_disk0() {
173
  $KPARTX -d -p- $1
174
}
175

    
176
cleanup() {
177
  # if something fails here, it souldn't call cleanup again...
178
  trap - EXIT
179

    
180
  if [ ${#CLEANUP[*]} -gt 0 ]; then
181
    LAST_ELEMENT=$((${#CLEANUP[*]}-1))
182
    REVERSE_INDEXES=$(seq ${LAST_ELEMENT} -1 0)
183
    for i in $REVERSE_INDEXES; do
184
        # If something fails here, it's better to retry it for a few times
185
        # before we give up with an error. This is needed for kpartx when
186
        # dealing with ntfs partitions mounted through fuse. umount is not
187
        # synchronous and may return while the partition is still busy. A
188
        # premature attempt to delete partition mappings through kpartx on a
189
        # device that hosts previously mounted ntfs partition may fail with an 
190
        # `device-mapper: remove ioctl failed: Device or resource busy'
191
        # error. A sensible workaround for this is to wait for a while and then
192
        # try again.
193
        local cmd=${CLEANUP[$i]}
194
        $cmd || for interval in 0.25 0.5 1 2 4; do
195
            echo "Command $cmd failed!"
196
            echo "I'll wait for $interval secs and will retry..."
197
            sleep $interval
198
            $cmd && break
199
        done
200
        test $? -eq 1 && { echo "Giving Up..."; exit 1; }
201
    done
202
  fi
203
  echo "Clean UP executed"
204
}
205

    
206
trap cleanup EXIT
207

    
208
DEFAULT_FILE="@defaultdir@/ganeti-instance-image"
209
if [ -f "$DEFAULT_FILE" ]; then
210
    . "$DEFAULT_FILE"
211
fi
212

    
213
# note: we don't set a default mirror since debian and ubuntu have
214
# different defaults, and it's better to use the default
215

    
216
# only if the user want to specify a mirror in the defaults file we
217
# will use it, this declaration is to make sure the variable is set
218
: ${CDINSTALL:="no"}
219
: ${BOOT:="no"}
220
: ${SWAP:="no"}
221
: ${SWAP_SIZE:="${INSTANCE_BE_memory}"}
222
: ${FILESYSTEM:="ext3"}
223
: ${KERNEL_ARGS=""}
224
: ${OVERLAY=""}
225
: ${IMAGE_NAME:=""}
226
: ${IMAGE_TYPE:="dump"}
227
: ${NOMOUNT:="no"}
228
: ${ARCH:="x86_64"}
229
: ${CUSTOMIZE_DIR:="@sysconfdir@/ganeti/instance-image/hooks"}
230
: ${VARIANTS_DIR:="@sysconfdir@/ganeti/instance-image/variants"}
231
: ${NETWORKS_DIR:="@sysconfdir@/ganeti/instance-image/networks"}
232
: ${OVERLAYS_DIR:="@sysconfdir@/ganeti/instance-image/overlays"}
233
: ${IMAGE_DIR:="@localstatedir@/cache/ganeti-instance-image"}
234
: ${IMAGE_DEBUG:="no"}
235
: ${TOOLS_DIR:="@osdir@/@osname@/tools"}
236

    
237
SCRIPT_NAME=$(basename $0)
238
KERNEL_PATH="$INSTANCE_HV_kernel_path"
239

    
240
if [ -f /sbin/blkid -a -x /sbin/blkid ]; then
241
    VOL_ID="/sbin/blkid -c /dev/null -o value -s UUID"
242
    VOL_TYPE="/sbin/blkid -c /dev/null -o value -s TYPE"
243
else
244
    for dir in /lib/udev /sbin; do
245
        if [ -f $dir/vol_id -a -x $dir/vol_id ]; then
246
            VOL_ID="$dir/vol_id -u"
247
            VOL_TYPE="$dir/vol_id -t"
248
        fi
249
    done
250
fi
251

    
252
if [ -z "$VOL_ID" ]; then
253
    log_error "vol_id or blkid not found, please install udev or util-linux"
254
    exit 1
255
fi
256

    
257

    
258
if [ -z "$OS_API_VERSION" -o "$OS_API_VERSION" = "5" ]; then
259
  OS_API_VERSION=5
260
  GETOPT_RESULT=`getopt -o o:n:i:b:s: -n '$0' -- "$@"`
261
  if [ $? != 0 ] ; then log_error "Terminating..."; exit 1 ; fi
262
  get_api5_arguments $GETOPT_RESULT
263
elif [ "$OS_API_VERSION" = "10" -o "$OS_API_VERSION" = "15" ]; then
264
  get_api10_arguments
265
elif [ "$OS_API_VERSION" = "20" ]; then
266
  get_api10_arguments
267
  get_api20_parameters
268
  IMAGE_NAME=$IMG_ID
269
  IMAGE_TYPE=$IMG_FORMAT
270
else
271
  log_error "Unknown OS API VERSION $OS_API_VERSION"
272
  exit 1
273
fi
274

    
275
if [ -n "$OS_VARIANT" ]; then
276
  if [ ! -d "$VARIANTS_DIR" ]; then
277
    log_error "OS Variants directory $VARIANTS_DIR doesn't exist"
278
    exit 1
279
  fi
280
  VARIANT_CONFIG="$VARIANTS_DIR/$OS_VARIANT.conf"
281
  if [ -f "$VARIANT_CONFIG" ]; then
282
    . "$VARIANT_CONFIG"
283
  else
284
    if grep -qxF "$OS_VARIANT" variants.list; then
285
      log_error "ERROR: instance-image configuration error"
286
      log_error "  Published variant $OS_VARIANT is missing its config file"
287
      log_error "  Please create $VARIANT_CONFIG or unpublish the variant"
288
      log_error "  (by removing $OS_VARIANT from variants.list)"
289
    else
290
      log_error "Unofficial variant $OS_VARIANT is unsupported"
291
      log_error "Most probably this is a user error, forcing a wrong name"
292
      log_error "To support this variant please create file $VARIANT_CONFIG"
293
    fi
294
    exit 1
295
  fi
296
fi
297