mkarchiso 8.06 KB
Newer Older
1
2
3
#!/bin/bash

CPIOCONFIG="$(pwd)/archiso-mkinitcpio.conf"
4
DEF_CONFIG_DIR="$(pwd)/overlay"
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
PKGFILE="$(pwd)/packages.list"
PKGLIST=""
QUIET="y"
FORCE="n"
ADDON_DIR=""

command_name=""
work_dir=""
imgname=""

APPNAME=$(basename "${0}")

# usage: usage <exitvalue>
usage ()
{
    echo "usage ${APPNAME} [options] command <command options>"
    echo " general options:"
    echo "    -f               Force overwrite of working files/squashfs image/bootable image"
    echo "    -i CPIO_CONFIG   Use CONFIG file for mkinitcpio. default: ${CPIOCONFIG}"
    echo "    -P PKGFILE       File with list of packages to install. default: ${PKGFILE}"
    echo "    -p PACKAGE       Additional package to install, can be used multiple times"
    echo "    -a ADDON_DIR     Use addons from DIR. default: none"
    echo "    -t <iso,disk>    Type of image to create. Defaults to iso."
    echo "    -v               Enable verbose output."
    echo "    -h               This message."
    echo " commands:"
31
32
    echo " install <working dir>          : where to build the image root"
    echo " squash <working dir>           : generate a squashfs image of the installed root"
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
    echo " img <working dir> <image name> : build an image from the working directory"
    echo " all <working dir> <image name> : perform all of the above, in order"
    exit $1
}

while getopts 'i:P:p:a:t:fvh' arg; do
    case "${arg}" in
        i) CPIOCONFIG="${OPTARG}" ;;
        P) PKGFILE="${OPTARG}" ;;
        p) PKGLIST="${PKGLIST} ${OPTARG}" ;;
        a) ADDON_DIR="${OPTARG}" ;;
        t) IMG_TYPE="${OPTARG}" ;;
        f) FORCE="y" ;;
        v) QUIET="n" ;;
        h|?) usage 0 ;;
        *) echo "invalid argument '${arg}'"; usage 1 ;;
    esac
done

shift $(($OPTIND - 1))
echo "ARGS: $@"

[ $# -le 1 ] && usage 1

# do UID checking here so someone can at least get usage instructions
if [ "$EUID" != "0" ]; then
    echo "error: This script must be run as root."
    exit 1
fi

command_name="${1}"
case "${command_name}" in
    install) work_dir="${2}" ;;
    squash) work_dir="${2}" ;;
    img) work_dir="${2}"; imgname="${3}" ;;
    all) work_dir="${2}"; imgname="${3}" ;;
    *) echo "invalid command name '${command_name}'"; usage 1 ;;
esac

[ "x${work_dir}" = "x" ] && (echo "please specify a working directory" && usage 1)

74
75
IMGROOT="${work_dir}/img"
INSTROOT="${work_dir}/install"
76
77
78

_kversion ()
{
79
    source ${INSTROOT}/etc/mkinitcpio.d/kernel26.kver
80
81
82
83
84
85
86
87
    echo ${ALL_kver}
}

# usage: _pacman <packages>...
_pacman ()
{
    local ret
    if [ "${QUIET}" = "y" ]; then
88
        mkarchroot -f ${INSTROOT} $* 2>&1 >/dev/null
89
90
        ret=$?
    else
91
        mkarchroot -f ${INSTROOT} $*
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
        ret=$?
    fi
    if [ $ret -ne 0 ]; then
        exit 1
    fi
}

# usage: install_pkgfile <packagesfile>
install_pkgfile ()
{
    if [ -e "${1}" ]; then
        toinstall=""
        while read pkg; do
            toinstall="${toinstall} ${pkg}"
        done < ${1}
        _pacman "${toinstall}"
    else
        echo "error: Package file '${1}' does not exist, aborting."
        exit 1
    fi
}

114
115

command_install () {
116
117
118
119
120
121
    echo "====> Installing/building image root"
    if [ -e "${work_dir}" -a "${FORCE}" = "n" ]; then
        echo "error: Working dir '${work_dir}' already exists, aborting."
        exit 1
    fi

122
123
    mkdir -p "${IMGROOT}"
    mkdir -p "${INSTROOT}"
124
125
126
127
128
129
130
131
132
133
134
135

    echo "Installing packages..."
    echo " Installing packages from '${PKGFILE}'"
    install_pkgfile "${PKGFILE}"

    for pkg in ${PKGLIST}; do
        echo "   Installing package '${pkg}'"
        _pacman "${pkg}"
    done

    echo "Updating kernel module dependencies"
    kernelver=$(_kversion)
136
    depmod -a -b "${INSTROOT}" "${kernelver}"
137
    # remove the initcpio images that were generated for the host system
138
    find "${INSTROOT}/boot" -name *.img -delete
139
140

    echo "Creating default home directory"
141
    install -d -o1000 -g100 -m0755 "${INSTROOT}/home/arch"
142
143
144

    # Cleanup
    echo "Cleaning up image root files..."
145
    find "${INSTROOT}" -name *.pacnew -name *.pacsave -name *.pacorig -delete
146
147
148
149

    # delete a lot of unnecessary cache/log files
    kill_dirs="var/abs var/cache/man var/cache/pacman var/log/* var/mail tmp/* initrd"
    for x in ${kill_dirs}; do
150
151
        if [ -e "${INSTROOT}/${x}" ]; then
            rm -rf "${INSTROOT}/${x}"
152
153
154
155
        fi
    done

    # pacman DBs are big, delete all sync dbs
156
    rm -rf "${INSTROOT}/var/lib/pacman/sync"
157
158

    # copy over kernel and grub configs for boot
159
160
161
162
    if [ -e "${INSTROOT}/boot" -a -e "${DEF_CONFIG_DIR}/boot" ]; then
        rm -rf "${IMGROOT}/boot"
        cp -r "${INSTROOT}/boot" "${IMGROOT}"
        cp -rf "${DEF_CONFIG_DIR}/boot" "${IMGROOT}"
163
164
165
    fi

    # TODO: this might belong somewhere else
166
    mkdir -p "${IMGROOT}/addons"
167
168
    if [ -d "${ADDON_DIR}" ]; then
        echo "Copying addons from ${ADDON_DIR}..."
169
        cp -r ${ADDON_DIR}/* "${IMGROOT}/addons"
170
171
172
    fi

    # always make an addon out of DEF_CONFIG_DIR
173
    echo "Creating default overlay..."
174
    if [ "${QUIET}" = "y" ]; then
175
        mksquashfs "${DEF_CONFIG_DIR}" "${IMGROOT}/addons/overlay.sqfs" -noappend >/dev/null
176
    else
177
        mksquashfs "${DEF_CONFIG_DIR}" "${IMGROOT}/addons/overlay.sqfs" -noappend
178
    fi
179
}
180

181
# command_squash path image
182
command_squash () {
183
    echo "====> Generating SquashFS image"
184
    imagename="${IMGROOT}/archlive.sqfs"
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    if [ -e "${imagename}" ]; then
        if [ "${FORCE}" = "y" ]; then
            echo -n "Removing old SquashFS image..."
            rm "${imagename}"
            echo "done."
        else
            echo "error: SquashFS image '${imagename}' already exists, aborting."
            exit 1
        fi
    fi

    echo "Creating squashfs image. This may take some time..."
    start=$(date +%s)
    if [ "${QUIET}" = "y" ]; then
199
        mksquashfs "${INSTROOT}" "${imagename}" -noappend >/dev/null
200
    else
201
        mksquashfs "${INSTROOT}" "${imagename}" -noappend
202
203
204
    fi
    minutes=$(echo $start $(date +%s) | awk '{ printf "%0.2f",($2-$1)/60 }')
    echo "Image creation done in $minutes minutes."
205
}
206

207
command_img () {
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    echo "====> Making bootable image"
    [ "x${imgname}" = "x" ] && (echo "Bootable image name must be specified" && usage 1)
    if [ -e "${imgname}" ]; then
        if [ "${FORCE}" = "y" ]; then
            echo "Removing existing bootable image..."
            rm -rf "${imgname}"
        else
            echo "error: Image '${imgname}' already exists, aborting."
            exit 1
        fi
    fi
    if [ ! -e "${CPIOCONFIG}" ]; then
        echo "error: mkinitcpio config '${CPIOCONFIG}' does not exist, aborting."
        exit 1
    fi

    kernelver=$(_kversion)
225
226
    basedir=${INSTROOT}
    [ "${INSTROOT:0:1}" != "/" ] && basedir="$(pwd)/${INSTROOT}"
227
228
    echo "Generating initcpio for image..."
    if [ "${QUIET}" = "y" ]; then
229
        mkinitcpio -c "${CPIOCONFIG}" -b "${basedir}" -k "${kernelver}" -g "${IMGROOT}/boot/archlive.img" >/dev/null
230
231
        ret=$?
    else
232
        mkinitcpio -c "${CPIOCONFIG}" -b "${basedir}" -k "${kernelver}" -g "${IMGROOT}/boot/archlive.img"
233
234
235
236
237
238
239
        ret=$?
    fi
    if [ $ret -ne 0 ]; then
        echo "error: initcpio image creation failed..."
        exit 1
    fi

240
    cp ${INSTROOT}/usr/lib/grub/i386-pc/* "${IMGROOT}/boot/grub"
241
242
243

    if [ "x$IMG_TYPE" == "xdisk" ]; then
        echo "Creating DISK image..."
244
        mkusbimg "${IMGROOT}" "${imgname}"
245
246
247
248
249
250
251
252
253
    else
        echo "Creating ISO image..."
        q=""
        [ "${QUIET}" = "y" ] && qflag="-q"
        mkisofs ${qflag} -r -l -b "boot/grub/stage2_eltorito" -uid 0 -gid 0 \
            -no-emul-boot -boot-load-size 4 -boot-info-table \
            -publisher "Arch Linux <archlinux.org>" \
            -input-charset=UTF-8 -p "prepared by $NAME" \
            -A "Arch Linux Live/Rescue CD" \
254
            -o "${imgname}" "${IMGROOT}"
255
    fi
256
257
258
259
260
261
262
263
264
265
266
267
}

# Go through the main commands in order. If 'all' was specified, then we want
# to do everything. Start with 'install'.
if [ "${command_name}" = "install" -o "${command_name}" = "all" ]; then
    command_install
fi
if [ "${command_name}" = "squash" -o "${command_name}" = "all" ]; then
    command_squash
fi
if [ "${command_name}" = "img" -o "${command_name}" = "all" ]; then
    command_img
268
269
270
fi

# vim:ts=4:sw=4:et: