Statistics
| Branch: | Revision:

root / common.sh.in @ 47dc6386

History | View | Annotate | Download (8.8 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
DUMP="@DUMP@"
22
RESTORE="@RESTORE@"
23
LOSETUP="@LOSETUP@"
24
KPARTX="@KPARTX@"
25
SFDISK="@SFDISK@"
26
QEMU_IMG="@QEMU_IMG@"
27
MKDIR_P="@MKDIR_P@"
28
NTFSCLONE="@NTFSCLONE@"
29
XMLSTARLET="@XMLSTARLET@"
30
INSTALL_MBR="@INSTALL_MBR@"
31

    
32
@WINSUPPORT_TRUE@windows_support="yes"
33

    
34
CLEANUP=( )
35

    
36
log_error() {
37
  echo "$@" >&2
38
}
39

    
40
debug() {
41
    [ "$IMAGE_DEBUG" == "1" -o "$IMAGE_DEBUG" == "yes" ] &&  $@ || :
42
}
43

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

    
52
      -o) old_name=$2; shift 2;;
53

    
54
      -b) blockdev=$2; shift 2;;
55

    
56
      -s) swapdev=$2; shift 2;;
57

    
58
      --) shift; break;;
59

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

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

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

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

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

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

    
169
unmap_disk0() {
170
  $KPARTX -d -p- $1
171
}
172

    
173
cleanup() {
174
  # if something fails here, it souldn't call cleanup again...
175
  trap - EXIT
176

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

    
203
trap cleanup EXIT
204

    
205
DEFAULT_FILE="@DEFAULT_DIR@/ganeti-instance-image"
206
if [ -f "$DEFAULT_FILE" ]; then
207
    . "$DEFAULT_FILE"
208
fi
209

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

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

    
234
SCRIPT_NAME=$(basename $0)
235
KERNEL_PATH="$INSTANCE_HV_kernel_path"
236

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

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

    
254

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

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