Add a sample script to create filesystem images from an installed tree

created by installworld+distribution with the -DNO_ROOT option.
This commit is contained in:
Brooks Davis 2013-05-16 14:38:12 +00:00
parent 5ada86640b
commit 561e967f2f
3 changed files with 368 additions and 0 deletions

View file

@ -0,0 +1,8 @@
# $FreeBSD$
SCRIPTS= makeroot.sh
MAN= makeroot.8
BINDIR?= /usr/sbin
.include <bsd.prog.mk>

View file

@ -0,0 +1,124 @@
.\"-
.\" Copyright (c) 2013 SRI International
.\" All rights reserved.
.\"
.\" This software was developed by SRI International and the University of
.\" Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
.\" ("CTSRD"), as part of the DARPA CRASH research programme.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.Dd May 16, 2013
.Dt MAKEROOT 8
.Os
.Sh NAME
.Nm makeroot
.Nd Tool to create root filesystem images given a tree containing a manifest
.Sh SYNOPSIS
.Nm
.Op Fl d
.Op Fl B Ar byte-order
.Op Fl e Ar extras-manifest
.Op Fl f Ar filelist
.Op Fl k Ar keydir Op Fl K Ar user
.Op Fl p Ar master.passwd Op Fl g Ar group
.Op Fl s Ar size
.Ar image-file
.Ar rootdir
.Sh DESCRIPTION
The
.Nm
script creates a UFS filesystem image into
.Ar imagefile .
By default,
all filesystem objects listed in the
METALOG file contained in the
.Pa Ar rootdir
directory will be placed in the root of the UFS image
.Ar image-file .
will be placed in the root of the UFS image
.Ar image-file .
.Pp
Images can be customized with a number of different flags.
.Bl -tag -compact -width indent
.It Fl B Ar byte-order
Set the byte order of the image to
.Ar byte-order .
This argument is passed directly to
.Xr makefs 8 .
.It Fl d
Enable debugging output.
.It Fl e Ar manifest
Extra files listed in the
.Xr nmtree 8
format
.Ar manifest
file are added to the filesystem image.
If no contents= tag is specified or a contents= tag is relative then
files are found relative to the basename of the full path of the
manifest.
If a contents= tag is provided and it is an absolute path then the file
will be from that path.
.It Fl f Ar filelist
Constrain set of filesystem objects included from
.Ar rootdir
to those listed (one per line) in the
.Ar filelist
plus any required directories.
.It Fl k Ar keydir Op Fl K Ar user
Create a .ssh/authorized_keys file from a collection of public key files
stored in
.Ar keydir
and install it in the home directory of
.Ar user .
If no
.F K
argument is supplied then the files will be installed in the root user's
directory.
.It Fl p Ar master.passwd Op Fl g Ar group
Install an alternate
.Ar master.passwd
file and optionally an alternative
.Ar group
file.
.It Fl s Ar size
Set the size of the image to
.Ar size .
The
.Fl s
argument is passed directly to
.Xr makefs 8 .
.El
.Sh EXAMPLES
.Dl $ makeroot.sh -k keys -K ctsrd -p extras/etc/master.passwd -g extras/etc/group -e extras/mdroot.mtree -e demo/demo.mtree -e extras/ctsrd.mtree -s 26112k -f demo.files cheribsd-demo.img /path/to/dist
.Sh SEE ALSO
.Xr mtree 5 ,
.Xr makefs 8 ,
.Xr nmtree 8
.Sh AUTHORS
This software and this manual page were developed by SRI International
and the University of Cambridge Computer Laboratory under DARPA/AFRL
contract
.Pq FA8750-10-C-0237
.Pq Do CTSRD Dc ,
as part of the DARPA CRASH research programme.

236
tools/tools/makeroot/makeroot.sh Executable file
View file

@ -0,0 +1,236 @@
#!/bin/sh -e
#-
# Copyright (c) 2012-2013 SRI International
# Copyright (c) 2012 Robert N. M. Watson
# All rights reserved.
#
# This software was developed by SRI International and the University of
# Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
# ("CTSRD"), as part of the DARPA CRASH research programme.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$
usage()
{
cat <<EOF 1>&2
usage: makeroot.sh [-B byte-order] [-d] [-e <extras manifest>] [-f <filelist>]
[-k <keydir> [-K <user>]]
[-p <master.passwd> [-g <groupfile>]] [-s <size>]
<image> <bsdroot>
EOF
exit 1
}
warn()
{
echo `basename $0` "$@" 1>&2
}
err()
{
ret=$1
shift
warn "$@"
exit $ret
}
atexit()
{
if [ -z "${DEBUG}" ]; then
rm -rf ${tmpdir}
else
warn "temp directory left at ${tmpdir}"
fi
}
DEBUG=
# Allow duplice manifest entries when not file list is given because the
# FreeBSD METALOG still includes it.
DUPFLAG=-D
EXTRAS=
FILELIST=
GROUP=
KEYDIR=
KEYUSERS=
PASSWD=
while getopts "Bde:f:g:K:k:p:s:" opt; do
case "$opt" in
B) BFLAG="-B ${OPTARG}" ;;
d) DEBUG=1 ;;
e) EXTRAS="${EXTRAS} ${OPTARG}" ;;
f) FILELIST="${OPTARG}"; DUPFLAG= ;;
g) GROUP="${OPTARG}" ;;
K) KEYUSERS="${KEYUSERS} ${OPTARG}" ;;
k) KEYDIR="${OPTARG}" ;;
p) PASSWD="${OPTARG}" ;;
s) SIZE="${OPTARG}" ;;
*) usage ;;
esac
done
shift $(($OPTIND - 1))
if [ $# -ne 2 ]; then
usage;
fi
IMGFILE=$(realpath $(dirname $1))/$(basename $1)
BSDROOT=$2
DBDIR=${BSDROOT}/etc
if [ ! -r ${BSDROOT}/METALOG ]; then
err 1 "${BSDROOT} does not contain a METALOG"
fi
if [ -n "${GROUP}" -a -z "${PASSWD}" ]; then
warn "-g requires -p"
usage
fi
if [ -n "${KEYUSERS}" -a -z "${KEYDIR}" ]; then
warn "-K requires -k"
usage
fi
if [ -n "${KEYDIR}" -a -z "${KEYUSERS}" ]; then
KEYUSERS=root
fi
tmpdir=`mktemp -d /tmp/makeroot.XXXXX`
if [ -z "${tmpdir}" -o ! -d "${tmpdir}" ]; then
err 1 "failed to create tmpdir"
fi
trap atexit EXIT
manifest=${tmpdir}/manifest
echo "#mtree 2.0" > ${manifest}
if [ -n "${PASSWD}" ]; then
cp ${PASSWD} ${tmpdir}/master.passwd
pwd_mkdb -d ${tmpdir} -p ${tmpdir}/master.passwd
if [ -z "${GROUP}" ]; then
cp ${DBDIR}/group ${tmpdir}
else
cp ${GROUP} ${tmpdir}
fi
cat <<EOF >> ${tmpdir}/passwd.mtree
./etc/group type=file uname=root gname=wheel mode=0644 contents=${tmpdir}/group
./etc/master.passwd type=file uname=root gname=wheel mode=0600 contents=${tmpdir}/master.passwd
./etc/passwd type=file mode=0644 uname=root gname=wheel contents=${tmpdir}/passwd
./etc/pwd.db type=file mode=0644 uname=root gname=wheel contents=${tmpdir}/pwd.db
./etc/spwd.db type=file mode=0600 uname=root gname=wheel contents=${tmpdir}/spwd.db
EOF
EXTRAS="${EXTRAS} ${tmpdir}/passwd.mtree"
DBDIR=${tmpdir}
fi
if [ -n "${FILELIST}" ]; then
# build manifest from root manifest and FILELIST
(echo .; grep -v ^# ${FILELIST} | while read path; do
# Print each included path and all its sub-paths with a ./
# prepended. The "sort -u" will then discard all the
# duplicate directory entries. This ensures that we
# extract the permissions for each unlisted directory
# from the METALOG.
path="/${path}"
while [ -n "${path}" ]; do
echo ".${path}"
path="${path%/*}"
done
done) | sort -u ${BSDROOT}/METALOG - | \
awk '
!/ type=/ { file = $1 }
/ type=/ { if ($1 == file) {print} }' >> ${manifest}
else
# Start with all the files in BSDROOT/METALOG except those in
# one of the EXTRAS manifests.
grep -h type=file ${EXTRAS} | cut -d' ' -f1 | \
sort -u ${BSDROOT}/METALOG - | awk '
!/ type=/ { file = $1 }
/ type=/ { if ($1 != file) {print} }' >> ${manifest}
fi
# For each extras file, add contents kyes relative to the directory the
# manifest lives in for each file line that does not have one. Adjust
# contents keys relative to ./ to be relative to the same directory.
for eman in ${EXTRAS}; do
if [ ! -f ${eman} ]; then
err 1 "${eman} is not a regular file"
fi
extradir=`realpath ${eman}`; extradir=`dirname ${extradir}`
awk '{
if ($0 !~ /type=file/) {
print
} else {
if ($0 !~ /contents=/) {
printf ("%s contents=%s\n", $0, $1)
} else {
print
}
}
}' ${eman} | \
sed -e "s|contents=\./|contents=${extradir}/|" >> ${manifest}
done
# /etc/rcorder.start allows the startup order to be stable even if
# not all startup scripts are installed. In theory it should be
# unnecessicary, but dependencies in rc.d appear to be under recorded.
# This is a hack local to beri/cheribsd.
#
echo /etc/rc.d/FIRST > ${tmpdir}/rcorder.start
rcorder -s nostart ${BSDROOT}/etc/rc.d/* | sed -e "s:^${BSDROOT}::" | \
grep -v LAST | grep -v FIRST >> \
${tmpdir}/rcorder.start
echo /etc/rc.d/LAST >> ${tmpdir}/rcorder.start
echo "./etc/rcorder.start type=file mode=644 uname=root gname=wheel" \
"contents=${tmpdir}/rcorder.start" >> ${manifest}
# Add all public keys in KEYDIR to roots' authorized_keys file.
if [ -n "${KEYDIR}" ]; then
cat ${KEYDIR}/*.pub > ${tmpdir}/authorized_keys
if [ ! -s ${tmpdir}/authorized_keys ]; then
err 1 "no keys found in ${KEYDIR}"
fi
for user in ${KEYUSERS}; do
userdir=`awk -F: "{if (\\\$1 == \"${user}\") {print \\\$9; exit} }" ${DBDIR}/master.passwd`
gid=`awk -F: "{if (\\\$1 == \"${user}\") {print \\\$4; exit} }" ${DBDIR}/master.passwd`
group=`awk -F: "{if (\\\$3 == \"${gid}\") {print \\\$1; exit} }" ${DBDIR}/group`
if [ -z "${userdir}" ]; then
err 1 "${user}: not found in ${DBDIR}/master.passwd"
fi
echo ".${userdir}/.ssh type=dir mode=700 uname=${user} gname=${group}" >> ${manifest}
echo ".${userdir}/.ssh/authorized_keys type=file mode=600 uname=${user} gname=${group} contents=${tmpdir}/authorized_keys" >> ${manifest}
done
fi
if [ -n "${SIZE}" ]; then
SIZEFLAG="-s ${SIZE}"
fi
cd ${BSDROOT}; makefs ${DUPFLAG} -N ${DBDIR} ${SIZEFLAG} ${BFLAG} \
-t ffs -f 256 ${IMGFILE} ${manifest}