Statistics
| Branch: | Revision:

root / common.sh.in @ 2ec7c7a8

History | View | Annotate | Download (12.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
MKDIR_P="@MKDIR_P@"
22
DUMP="@DUMP@"
23
LOSETUP="@LOSETUP@"
24
KPARTX="@KPARTX@"
25
SFDISK="@SFDISK@"
26
QEMU_IMG="@QEMU_IMG@"
27

    
28
CLEANUP=( )
29

    
30
log_error() {
31
  echo "$@" >&2
32
}
33

    
34
debug() {
35
    [ "$IMAGE_DEBUG" == "1" -o "$IMAGE_DEBUG" == "yes" ] &&  $@ || :
36
}
37

    
38
get_api5_arguments() {
39
  GETOPT_RESULT=$*
40
  # Note the quotes around `$TEMP': they are essential!
41
  eval set -- "$GETOPT_RESULT"
42
  while true; do
43
    case "$1" in
44
      -i|-n) instance=$2; shift 2;;
45

    
46
      -o) old_name=$2; shift 2;;
47

    
48
      -b) blockdev=$2; shift 2;;
49

    
50
      -s) swapdev=$2; shift 2;;
51

    
52
      --) shift; break;;
53

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

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

    
101
get_os_type() {
102
    target=$1
103
    if [ -z "${target}" ] ; then
104
        log_error "target is not set in get_os_type"
105
        exit 1
106
    fi
107
    if [ -e ${target}/etc/redhat-release ] ; then
108
        OS_TYPE="redhat"
109
    elif [ -e ${target}/etc/debian_version ] ; then
110
        OS_TYPE="debian"
111
    elif [ -e ${target}/etc/gentoo-release ] ; then
112
        OS_TYPE="gentoo"
113
    elif [ -e ${target}/etc/SuSE-release ] ; then
114
        OS_TYPE="suse"
115
    fi
116
}
117

    
118
get_os() {
119
    target=$1
120
    if [ -z "${target}" ] ; then
121
        log_error "target is not set in get_os"
122
        exit 1
123
    fi
124
    lsb="/usr/bin/lsb_release"
125
    if [ -e $lsb ] ; then
126
        OPERATING_SYSTEM="$(chroot ${target} ${lsb} -i -s | tr "[:upper:]" "[:lower:]")"
127
    elif [ -e ${target}/etc/debian_version ] ; then
128
        OPERATING_SYSTEM="debian"
129
    elif [ -e ${target}/etc/gentoo-release ] ; then
130
        OPERATING_SYSTEM="gentoo"
131
    elif [ -e ${target}/etc/fedora-release ] ; then
132
        OPERATING_SYSTEM="fedora"
133
    elif [ -e ${target}/etc/redhat-release ] ; then
134
        if [ -n "$(grep -i centos ${target}/etc/redhat-release)" ] ; then
135
            OPERATING_SYSTEM="centos"
136
        else
137
            OPERATING_SYSTEM="redhat"
138
        fi
139
    fi
140
}
141

    
142
get_os_release() {
143
    target=$1
144
    if [ -z "${target}" ] ; then
145
        log_error "target is not set in get_os_release"
146
        exit 1
147
    fi
148
    lsb="/usr/bin/lsb_release"
149
    if [ -e $lsb ] ; then
150
        OS_RELEASE="$(chroot ${target} ${lsb} -r -s | tr "[:upper:]" "[:lower:]")"
151
    elif [ -e ${target}/etc/debian_version ] ; then
152
        OS_RELEASE="$(cat ${target}/etc/debian_version)"
153
    elif [ -e ${target}/etc/fedora-release ] ; then
154
        OS_RELEASE="$(cat ${target}/etc/fedora-release | awk '{print $3}')"
155
    elif [ -e ${$target}/etc/redhat-release ] ; then
156
        OS_RELEASE="$(cat ${target}/etc/redhat-release | awk '{print $3}')"
157
    fi
158
}
159

    
160
format_disk0() {
161
    local sfdisk_cmd="$SFDISK -uM -H 255 -S 63 --quiet --Linux --DOS $1"
162
    if [  "${SWAP}" = "yes" -a -z "${KERNEL_PATH}" ] ; then
163
        # Create three partitions:
164
        # 1 - 100MB /boot, bootable
165
        # 2 - Size of Memory, swap
166
        # 3 - Rest
167
        $sfdisk_cmd > /dev/null <<EOF
168
,100,L,*
169
,${SWAP_SIZE},S
170
,,L
171
EOF
172
    elif [  "${SWAP}" = "no" -a -z "${KERNEL_PATH}" ] ; then
173
        # Create two partitions:
174
        # 1 - 100MB /boot, bootable
175
        # 2 - Rest
176
        $sfdisk_cmd > /dev/null <<EOF
177
,100,L,*
178
,,L
179
EOF
180
    elif [  "${SWAP}" = "yes" -a -n "${KERNEL_PATH}" ] ; then
181
        # Create two partitions:
182
        # 1 - Size of Memory, swap
183
        # 2 - Rest
184
        $sfdisk_cmd > /dev/null <<EOF
185
,$SWAP_SIZE,S
186
,,L
187
EOF
188
    elif [  "${SWAP}" = "no" -a -n "${KERNEL_PATH}" ] ; then
189
        # Create two partitions:
190
        # 1 - Whole
191
        $sfdisk_cmd > /dev/null <<EOF
192
,,L
193
EOF
194
    fi
195
}
196

    
197
mkfs_disk0() {
198
    local mkfs="mkfs.${FILESYSTEM}"
199
    # Format /
200
    $mkfs -Fq -L / $root_dev > /dev/null
201
    # Format /boot
202
    if [ -n "${boot_dev}" ] ; then
203
        $mkfs -Fq -L /boot $boot_dev > /dev/null
204
    fi
205
    # Format swap
206
    if [ -n "${swap_dev}" ] ; then
207
        # Format swap
208
        mkswap -f $swap_dev > /dev/null
209
    fi
210
    # During reinstalls, ext4 needs a little time after a mkfs so add it here
211
    # and also run a sync to be sure.
212
    sync
213
    sleep 2
214
}
215

    
216
mount_disk0() {
217
    local target=$1
218
    mount $root_dev $target
219
    CLEANUP+=("umount $target")
220
    if [ -n "${boot_dev}" ] ; then
221
        $MKDIR_P $target/boot
222
        mount $boot_dev $target/boot
223
        CLEANUP+=("umount $target/boot")
224
    fi
225
    # sync the file systems before unmounting to ensure everything is flushed
226
    # out
227
    CLEANUP+=("sync")
228
}
229

    
230
map_disk0() {
231
    blockdev="$1"
232
    filesystem_dev_base=`$KPARTX -l -p- $blockdev | \
233
                            grep -m 1 -- "-1.*$blockdev" | \
234
                            $AWK '{print $1}'`
235
    if [ -z "$filesystem_dev_base" ]; then
236
        log_error "Cannot interpret kpartx output and get partition mapping"
237
        exit 1
238
    fi
239
    $KPARTX -a -p- $blockdev > /dev/null
240
    filesystem_dev="/dev/mapper/${filesystem_dev_base/%-1/}"
241
    if [ ! -b "/dev/mapper/$filesystem_dev_base" ]; then
242
        log_error "Can't find kpartx mapped partition: /dev/mapper/$filesystem_dev_base"
243
        exit 1
244
    fi
245
    echo "$filesystem_dev"
246
}
247

    
248
map_partition() {
249
    filesystem_dev="$1"
250
    partition="$2"
251
    if [ "${SWAP}" = "yes" -a -z "${KERNEL_PATH}" ] ; then
252
        boot_dev="${filesystem_dev}-1"
253
        swap_dev="${filesystem_dev}-2"
254
        root_dev="${filesystem_dev}-3"
255
    elif [ "${SWAP}" = "no" -a -z "${KERNEL_PATH}" ] ; then
256
        boot_dev="${filesystem_dev}-1"
257
        root_dev="${filesystem_dev}-2"
258
    elif [ "${SWAP}" = "yes" -a -n "${KERNEL_PATH}" ] ; then
259
        swap_dev="${filesystem_dev}-1"
260
        root_dev="${filesystem_dev}-2"
261
    elif [ "${SWAP}" = "no" -a -n "${KERNEL_PATH}" ] ; then
262
        root_dev="${filesystem_dev}-1"
263
    fi
264
    echo "$(eval "echo \${$(echo ${partition}_dev)"})"
265
}
266

    
267
unmap_disk0() {
268
  $KPARTX -d -p- $1
269
}
270

    
271
setup_fstab() {
272
    local target=$1 fs=${FILESYSTEM}
273
    get_os_type $target
274
    cat > $target/etc/fstab <<EOF
275
# /etc/fstab: static file system information.
276
#
277
# <file system>   <mount point>   <type>  <options>       <dump>  <pass>
278
UUID=$root_uuid   /               $fs     defaults        0       1
279
proc              /proc           proc    defaults        0       0
280
EOF
281

    
282
if [ -n "$boot_dev" -a -n "$boot_uuid" ] ; then
283
    cat >> $target/etc/fstab <<EOF
284
UUID=$boot_uuid   /boot           $fs     defaults        1       2
285
EOF
286
fi
287

    
288
if [ -n "$swap_dev" -a -n "$swap_uuid" ] ; then
289
    cat >> $target/etc/fstab <<EOF
290
UUID=$swap_uuid   swap            swap    defaults        0       0
291
EOF
292
fi
293

    
294
# OS Specific fstabs
295
if [ "$OS_TYPE" = "redhat" ] ; then
296
    cat >> $target/etc/fstab <<EOF
297
tmpfs             /dev/shm        tmpfs   defaults        0       0
298
devpts            /dev/pts        devpts  gid=5,mode=620  0       0
299
sysfs             /sys            sysfs   defaults        0       0
300
EOF
301
fi
302

    
303
if [ "$OS_TYPE" = "gentoo" ] ; then
304
    cat >> $target/etc/fstab <<EOF
305
shm               /dev/shm        tmpfs   nodev,nosuid,noexec 0   0
306
EOF
307
fi
308
}
309

    
310
setup_console() {
311
    local target=$1
312
    if [ -z "$target" ] ; then
313
        log_error "target not set for setup_console"
314
        exit 1
315
    fi
316
    # Upstart is on this system, so do this instead
317
    if [ -e ${target}/etc/event.d/tty1 ] ; then
318
        cat ${target}/etc/event.d/tty1 | sed -re 's/tty1/ttyS0/' \
319
            > ${target}/etc/event.d/ttyS0
320
        return
321
    fi
322
    # upstart in karmic and newer
323
    if [ -e ${target}/etc/init/tty1.conf ] ; then
324
        cat ${target}/etc/init/tty1.conf | \
325
        sed -re 's/^exec.*/exec \/sbin\/getty -L 115200 ttyS0 vt102/' \
326
            > ${target}/etc/init/ttyS0.conf
327
        sed -ie 's/tty1/ttyS0/g' ${target}/etc/init/ttyS0.conf
328
        return
329
    fi
330
    get_os $target
331
    case $OPERATING_SYSTEM in
332
        gentoo)
333
            sed -i -e 's/.*ttyS0.*/s0:12345:respawn:\/sbin\/agetty 115200 ttyS0 vt100/' \
334
                ${target}/etc/inittab
335
            ;;
336
        centos)
337
            echo "s0:12345:respawn:/sbin/agetty 115200 ttyS0 vt100" >> \
338
                ${target}/etc/inittab
339
            ;;
340
        debian|ubuntu)
341
            sed -i -e 's/.*T0.*/T0:23:respawn:\/sbin\/getty -L ttyS0 115200 vt100/' \
342
                ${target}/etc/inittab
343
            ;;
344
        *)
345
            echo "No support for your OS in instance-image, skipping..."
346
            ;;
347
    esac
348
}
349

    
350
cleanup() {
351
  if [ ${#CLEANUP[*]} -gt 0 ]; then
352
    LAST_ELEMENT=$((${#CLEANUP[*]}-1))
353
    REVERSE_INDEXES=$(seq ${LAST_ELEMENT} -1 0)
354
    for i in $REVERSE_INDEXES; do
355
      ${CLEANUP[$i]}
356
    done
357
  fi
358
}
359

    
360
trap cleanup EXIT
361

    
362
DEFAULT_FILE="@DEFAULT_DIR@/ganeti-instance-image"
363
if [ -f "$DEFAULT_FILE" ]; then
364
    . "$DEFAULT_FILE"
365
fi
366

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

    
370
# only if the user want to specify a mirror in the defaults file we
371
# will use it, this declaration is to make sure the variable is set
372
: ${CDINSTALL:="no"}
373
: ${SWAP:="yes"}
374
: ${SWAP_SIZE:="${INSTANCE_BE_memory}"}
375
: ${FILESYSTEM:="ext3"}
376
: ${KERNEL_ARGS=""}
377
: ${OVERLAY=""}
378
: ${IMAGE_NAME:=""}
379
: ${IMAGE_TYPE:="dump"}
380
: ${NOMOUNT:="no"}
381
: ${ARCH:=""}
382
: ${CUSTOMIZE_DIR:="@sysconfdir@/ganeti/instance-image/hooks"}
383
: ${VARIANTS_DIR:="@sysconfdir@/ganeti/instance-image/variants"}
384
: ${NETWORKS_DIR:="@sysconfdir@/ganeti/instance-image/networks"}
385
: ${OVERLAYS_DIR:="@sysconfdir@/ganeti/instance-image/overlays"}
386
: ${IMAGE_DIR:="@localstatedir@/cache/ganeti-instance-image"}
387
: ${IMAGE_DEBUG:="no"}
388

    
389
SCRIPT_NAME=$(basename $0)
390
KERNEL_PATH="$INSTANCE_HV_kernel_path"
391

    
392
if [ -f /sbin/blkid -a -x /sbin/blkid ]; then
393
    VOL_ID="/sbin/blkid -c /dev/null -o value -s UUID"
394
    VOL_TYPE="/sbin/blkid -c /dev/null -o value -s TYPE"
395
else
396
    for dir in /lib/udev /sbin; do
397
        if [ -f $dir/vol_id -a -x $dir/vol_id ]; then
398
            VOL_ID="$dir/vol_id -u"
399
            VOL_TYPE="$dir/vol_id -t"
400
        fi
401
    done
402
fi
403

    
404
if [ -z "$VOL_ID" ]; then
405
    log_error "vol_id or blkid not found, please install udev or util-linux"
406
    exit 1
407
fi
408

    
409

    
410
if [ -z "$OS_API_VERSION" -o "$OS_API_VERSION" = "5" ]; then
411
  OS_API_VERSION=5
412
  GETOPT_RESULT=`getopt -o o:n:i:b:s: -n '$0' -- "$@"`
413
  if [ $? != 0 ] ; then log_error "Terminating..."; exit 1 ; fi
414
  get_api5_arguments $GETOPT_RESULT
415
elif [ "$OS_API_VERSION" = "10" -o "$OS_API_VERSION" = "15" ]; then
416
  get_api10_arguments
417
else
418
  log_error "Unknown OS API VERSION $OS_API_VERSION"
419
  exit 1
420
fi
421

    
422
if [ -n "$OS_VARIANT" ]; then
423
  if [ ! -d "$VARIANTS_DIR" ]; then
424
    log_error "OS Variants directory $VARIANTS_DIR doesn't exist"
425
    exit 1
426
  fi
427
  VARIANT_CONFIG="$VARIANTS_DIR/$OS_VARIANT.conf"
428
  if [ -f "$VARIANT_CONFIG" ]; then
429
    . "$VARIANT_CONFIG"
430
  else
431
    if grep -qxF "$OS_VARIANT" variants.list; then
432
      log_error "ERROR: instance-image configuration error"
433
      log_error "  Published variant $OS_VARIANT is missing its config file"
434
      log_error "  Please create $VARIANT_CONFIG or unpublish the variant"
435
      log_error "  (by removing $OS_VARIANT from variants.list)"
436
    else
437
      log_error "Unofficial variant $OS_VARIANT is unsupported"
438
      log_error "Most probably this is a user error, forcing a wrong name"
439
      log_error "To support this variant please create file $VARIANT_CONFIG"
440
    fi
441
    exit 1
442
  fi
443
fi
444