mkarchiso 7.72 KB
Newer Older
1
2
3
4
5
6
#!/bin/bash

CPIOCONFIG="$(pwd)/archiso-mkinitcpio.conf"
PKGLIST=""
QUIET="y"
FORCE="n"
7
MOUNTFILE="$(pwd)/mounts"
8
9
10
11
12
13
14
15
16
17

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}"
18
    echo "    -p PACKAGE(S)    Additional package(s) to install, can be used multiple times"
19
20
21
22
    echo "    -t <iso,disk>    Type of image to create. Defaults to iso."
    echo "    -v               Enable verbose output."
    echo "    -h               This message."
    echo " commands:"
23
24
25
    echo " install <working dir> <pkg file> : install packages to the working dir"
    echo " squash <working dir> <sqfs name> : generate a squashfs image of the working dir"
    echo " img <working dir> <image name>   : build an image from the working dir"
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
    exit $1
}

while getopts 'i:P:p:a:t:fvh' arg; do
    case "${arg}" in
        i) CPIOCONFIG="${OPTARG}" ;;
        p) PKGLIST="${PKGLIST} ${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}"
53
54
55
work_dir=""
imgname=""

56
case "${command_name}" in
57
    install) work_dir="${2}"; imgname="none" ;;
58
    squash) work_dir="${2}"; imgname="${3}" ;;
59
60
61
62
    img) work_dir="${2}"; imgname="${3}" ;;
    *) echo "invalid command name '${command_name}'"; usage 1 ;;
esac

63
64
[ "x${imgname}" = "x" ] && (echo "Image name must be specified" && usage 1)
[ "x${work_dir}" = "x" ] && (echo "Please specify a working directory" && usage 1)
65
66
67

_kversion ()
{
68
69
    # Man this is gross... we need a better way to get the kernel version
    source ${work_dir}/etc/mkinitcpio.d/kernel26.kver
70
71
72
73
74
75
76
77
    echo ${ALL_kver}
}

# usage: _pacman <packages>...
_pacman ()
{
    local ret
    if [ "${QUIET}" = "y" ]; then
78
        mkarchroot -f ${work_dir} $* 2>&1 >/dev/null
79
80
        ret=$?
    else
81
        mkarchroot -f ${work_dir} $*
82
83
        ret=$?
    fi
84
85
86
87

    # Cleanup
    find "${work_dir}" -name *.pacnew -name *.pacsave -name *.pacorig -delete

88
89
90
91
92
    if [ $ret -ne 0 ]; then
        exit 1
    fi
}

93
command_install () {
94
    echo "====> Installing packages to '${work_dir}'"
95
96
97
98
99
    if [ -e "${work_dir}" -a "${FORCE}" = "n" ]; then
        echo "error: Working dir '${work_dir}' already exists, aborting."
        exit 1
    fi

100
    mkdir -p "${work_dir}"
101
102
103
104
105
106
107
108

    echo "Installing packages..."

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

109
110
111
112
113
    if [ -d "${work_dir}/lib/modules/" ]; then
        echo "Updating kernel module dependencies"
        kernelver=$(_kversion)
        depmod -a -b "${work_dir}" "${kernelver}"
    fi
114

115
116
117
118
119
    echo "Cleaning up what we can"
    if [ -d "${work_dir}/boot/" ]; then
        # remove the initcpio images that were generated for the host system
        find "${work_dir}/boot" -name *.img -delete
    fi
120

121
122
123
124
125
    #TODO is this needed? do it at the Makefile level?
    if [ -d "${work_dir}/home/" ]; then
        echo "Creating default home directory"
        install -d -o1000 -g100 -m0755 "${work_dir}/home/arch"
    fi
126
127
128
129

    # 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
130
131
        if [ -e "${work_dir}/${x}" ]; then
            rm -rf "${work_dir}/${x}"
132
133
134
135
        fi
    done

    # pacman DBs are big, delete all sync dbs
136
    rm -rf "${work_dir}/var/lib/pacman/sync"
137

138
139
    #TODO test for existance
    cp "${MOUNTFILE}" "${work_dir}/mounts"
140
141

    # always make an addon out of DEF_CONFIG_DIR
142
143
144
145
146
147
    #echo "Creating default overlay..."
    #if [ "${QUIET}" = "y" ]; then
    #    mksquashfs "${DEF_CONFIG_DIR}" "${work_dir}/addons/overlay.sqfs" -noappend >/dev/null
    #else
    #    mksquashfs "${DEF_CONFIG_DIR}" "${work_dir}/addons/overlay.sqfs" -noappend
    #fi
148
}
149

150
# command_squash path image
151
command_squash () {
152
153
    echo "====> Generating SquashFS image ${imgname}"
    if [ -e "${imgname}" ]; then
154
155
        if [ "${FORCE}" = "y" ]; then
            echo -n "Removing old SquashFS image..."
156
            rm "${imgname}"
157
158
            echo "done."
        else
159
            echo "error: SquashFS image '${imgname}' already exists, aborting."
160
161
162
163
            exit 1
        fi
    fi

164
    echo "Creating SquashFS image. This may take some time..."
165
166
    start=$(date +%s)
    if [ "${QUIET}" = "y" ]; then
167
        mksquashfs "${work_dir}" "${imgname}" -noappend >/dev/null
168
    else
169
        mksquashfs "${work_dir}" "${imgname}" -noappend
170
171
172
    fi
    minutes=$(echo $start $(date +%s) | awk '{ printf "%0.2f",($2-$1)/60 }')
    echo "Image creation done in $minutes minutes."
173
}
174

175
command_img () {
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
    echo "====> Making bootable image"
    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)
192
193
    basedir=${work_dir}
    [ "${work_dir:0:1}" != "/" ] && basedir="$(pwd)/${work_dir}"
194
195
    echo "Generating initcpio for image..."
    if [ "${QUIET}" = "y" ]; then
196
        mkinitcpio -c "${CPIOCONFIG}" -b "${basedir}" -k "${kernelver}" -g "${work_dir}/boot/archiso.img" >/dev/null
197
198
        ret=$?
    else
199
        mkinitcpio -c "${CPIOCONFIG}" -b "${basedir}" -k "${kernelver}" -g "${work_dir}/boot/archiso.img"
200
201
202
203
204
205
206
        ret=$?
    fi
    if [ $ret -ne 0 ]; then
        echo "error: initcpio image creation failed..."
        exit 1
    fi

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    USE_GRUB=1
    bootflags=""
    if [ "$USE_GRUB" = "1" ]; then
        _pacman grub #grub-gfx ??
        mkdir -p "${work_dir}/boot/grub"
        cp "${work_dir}/usr/lib/grub/i386-pc/*" "${work_dir}/boot/grub"

        # copy over kernel and grub configs for boot
        if [ -d "${work_dir}/boot" -a -e "${DEF_CONFIG_DIR}/boot" ]; then
            rm -rf "${work_dir}/boot"
            cp -r "${work_dir}/boot" "${work_dir}"
            cp -rf "${DEF_CONFIG_DIR}/boot" "${work_dir}"
        fi
        bootflags="boot/grub/stage2_eltorito"
    else
        _pacman isolinux
        bootflags="boot/whatever/isolinux"
    fi
225
226
227

    if [ "x$IMG_TYPE" == "xdisk" ]; then
        echo "Creating DISK image..."
228
        mkusbimg "${work_dir}" "${imgname}"
229
230
    else
        echo "Creating ISO image..."
231
232
233
234
        if [ -z "$bootflags" ]; then
            echo "Eeek, no boot flags found. This probably won't be bootable"
        fi
        qflag=""
235
        [ "${QUIET}" = "y" ] && qflag="-q"
236
        mkisofs ${qflag} -r -l $bootflags -uid 0 -gid 0 \
237
238
            -no-emul-boot -boot-load-size 4 -boot-info-table \
            -publisher "Arch Linux <archlinux.org>" \
239
            -input-charset=UTF-8 -p "prepared by mkarchiso" \
240
            -A "Arch Linux Live/Rescue CD" \
241
            -o "${imgname}" "${work_dir}"
242
    fi
243
244
245
246
247
248
249
250
251
252
253
254
}

# 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
255
256
257
fi

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