summaryrefslogtreecommitdiff
path: root/scripts/install-image
blob: 201500e3a1edfb7c0c7e4f89b46b633b3465e873 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/bin/bash

# this script installs a new release image into a running "union-installed"
# system to the new release. the specified image is a release ISO image.
# the script sets up a new union mount for the new release. a reboot is
# then required to boot into the newly installed release.

NEW_ISO=$1

PI_ROOT=''
SQUASH_MOUNT=''
ISO_MOUNT=''
TMP_DIR=''

vyatta_sysconfdir=/opt/vyatta/etc

failure_exit () {
  echo "$*"
  exit 1
}

clean_up () {
  if [ -n "$PI_ROOT" ] && [ -d "$PI_ROOT" ]; then
    umount $PI_ROOT >&/dev/null || true
  fi
  if [ -n "$SQUASH_MOUNT" ] && [ -d "$SQUASH_MOUNT" ]; then
    umount $SQUASH_MOUNT >&/dev/null || true
  fi
  if [ -n "$ISO_MOUNT" ] && [ -d "$ISO_MOUNT" ]; then
    umount $ISO_MOUNT >&/dev/null || true
  fi
  if [ -n "$TMP_DIR" ] && [ -d "$TMP_DIR" ]; then
    rm -rf $TMP_DIR
  fi
  PI_ROOT=''
  SQUASH_MOUNT=''
  ISO_MOUNT=''
  TMP_DIR=''
}

sig_handler () {
  echo "ERROR: Signal received. Exiting..."
  clean_up
  echo "Done"
  trap - EXIT
  exit 1
}

exit_handler () {
  echo "Exiting..."
  clean_up
  echo "Done"
}

trap sig_handler INT KILL
trap exit_handler EXIT

if [ `whoami` != 'root' ] ; then
  failure_exit 'This script must be run with root privileges.'
fi

# make sure it's a union-installed system
CURVER=$(sed -n 's/^Version \+: \+\([^ ]\+\)$/\1/p' \
           ${vyatta_sysconfdir}/version 2>/dev/null)
if [ -z "$CURVER" ]; then
  failure_exit 'Cannot find current version.'
fi
if [ ! -d "/live/image/boot/$CURVER" ] \
    || ! grep -q ' /live/image ' /proc/mounts \
    || grep -q ' /live/image iso9660 ' /proc/mounts \
    || ! grep -q " /$CURVER.squashfs " /proc/mounts; then
  failure_exit 'This script can only be used on a "union-installed" system.'
fi

# check the ISO
if [ ! -f "$NEW_ISO" ] || ! (file $NEW_ISO | grep -q 9660); then
  failure_exit "\"$NEW_ISO\" is not a valid ISO image file."
fi
TMP_DIR=$(mktemp -d /tmp/install-image.XXXXXX) \
  || failure_exit 'Failed to create temporary directory.'
ISO_MOUNT=$TMP_DIR/iso-mount
if ! mkdir $ISO_MOUNT || ! mount -o loop,ro "$NEW_ISO" $ISO_MOUNT; then
  failure_exit 'Failed to mount ISO image.'
fi

# check the squashfs image
SQUASH_FILE=$ISO_MOUNT/live/filesystem.squashfs
if [ ! -f "$SQUASH_FILE" ] || ! (file $SQUASH_FILE | grep -q Squashfs) \
    || ! grep -q '^ii  vyatta-version ' $ISO_MOUNT/live/packages.txt; then
  failure_exit "\"$NEW_ISO\" is not a Vyatta ISO image file."
fi
SQUASH_MOUNT=$TMP_DIR/squash-mount
if ! mkdir $SQUASH_MOUNT \
    || ! mount -o loop,ro "$SQUASH_FILE" $SQUASH_MOUNT; then
  failure_exit 'Failed to mount squashfs image.'
fi

# get version string
NEWVER=$(grep '^Version ' ${SQUASH_MOUNT}${vyatta_sysconfdir}/version \
          | tr -s ' ' | cut -d ' ' -f 3)
if [ -z "$NEWVER" ]; then
  failure_exit 'Cannot find new release version.'
fi
if [ "$CURVER" == "$NEWVER" ]; then
  failure_exit "Cannot install the same release version \"$NEWVER\"."
fi

# start the install
echo "Installing \"$NEWVER\" release."

# create the new release directories
REL_ROOT="/live/image/boot/$NEWVER"
RW_DIR="$REL_ROOT/live-rw"
if ! mkdir -p "$RW_DIR"; then
  failure_exit 'Cannot create directory for new release.'
fi

# copy the squashfs image and boot files
echo -n "Copying new release files..."
cp -p $SQUASH_FILE $REL_ROOT/$NEWVER.squashfs >&/dev/null
cp -p $SQUASH_MOUNT/boot/* $REL_ROOT/ >&/dev/null
echo " Done"

# mount copied squashfs
umount $SQUASH_MOUNT
SQUASH_FILE=$REL_ROOT/$NEWVER.squashfs
if ! mount -o loop,ro "$SQUASH_FILE" $SQUASH_MOUNT; then
  failure_exit 'Failed to mount new squashfs image.'
fi

# set up root for postinst
PI_ROOT=$TMP_DIR/pi_root
if ! mkdir $PI_ROOT \
    || ! mount -t unionfs -o noatime,dirs=$RW_DIR=rw:$SQUASH_MOUNT=ro unionfs \
          $PI_ROOT; then
  failure_exit 'Failed to set up root directory for postinst.'
fi

# set up /var/run fstab entry
PI_FSTAB=$PI_ROOT/etc/fstab
if ! grep -q 'tmpfs /var/run ' $PI_FSTAB >&/dev/null; then
  # replace the fstab. the default one has header that will cause
  # it to be wiped out on live boot.
  echo 'tmpfs /var/run tmpfs nosuid,nodev 0 0' >$PI_FSTAB
fi

# postinst hook
PI_SCRIPT=${PI_ROOT}${vyatta_sysconfdir}/install-image/postinst
if [ -e "$PI_SCRIPT" ]; then
  echo "running post-install script"
  $PI_SCRIPT $PI_ROOT
fi

# set up grub entry (if provided)
DEF_GRUB=${PI_ROOT}${vyatta_sysconfdir}/grub/default-union-grub-entry
if [ -e "$DEF_GRUB" ]; then
  old_grub_cfg=/live/image/boot/grub/grub.cfg
  new_grub_cfg=$TMP_DIR/grub.cfg
  sed -n '/^menuentry/q;p' $old_grub_cfg >$new_grub_cfg
  cat $DEF_GRUB >>$new_grub_cfg
  sed -n '/^menuentry/,${p}' $old_grub_cfg >>$new_grub_cfg
  sed -i 's/^set default=[0-9]\+$/set default=0/' $new_grub_cfg
  mv $new_grub_cfg $old_grub_cfg
fi

# done
exit 0