Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jail: Add archive subcommand and create method #795

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/bin/poudriere-jail.8
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
.Sh SYNOPSIS
.Nm poudriere
.Cm jail
.Fl A Ar archive
.Fl j Ar name
.Op Fl T -A args
.Fl c
.Fl j Ar name
.Op Fl bDx
Expand Down Expand Up @@ -95,7 +98,10 @@ This command manages the
.Nm
jails which are used as different building environments.
.Sh SUBCOMMANDS
.Bl -tag -width "-r name"
.Bl -tag -width "-A archive"
.It Fl A Ar archive
Create an archive of a jail suitable for use with the archive method of
the create subcommand.
.It Fl c
Create a jail.
See
Expand Down Expand Up @@ -201,6 +207,9 @@ Pre-built distribution options:
.It Cm allbsd
Fetch from
.Lk http://www.allbsd.org .
.It Cm archive= Ns Ar archive
Extract an archive created by the archive subcommand
.Po Fl A Ar archive Pc .
.It Cm ftp
Fetch from the host specified in the
.Va FREEBSD_HOST
Expand Down Expand Up @@ -319,6 +328,12 @@ as the
source tree mounted inside the jail
or from the host for
.Fl m Cm null .
.It Fl T Ar args
Pass the argument to tar as an unquoted string when creating an archive with
the archive subcommand
.Po Fl A Ar archive Pc .
This can be used to specify compression or archive format.
.Pq default: -a
.It Fl t Ar version
Upgrade the jail to the specified
.Ar version
Expand Down
165 changes: 131 additions & 34 deletions src/share/poudriere/jail.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ usage() {
poudriere jail [parameters] [options]

Parameters:
-A archive -- Archive a jail
-c -- Create a jail
-d -- Delete a jail
-i -- Show information about a jail
Expand Down Expand Up @@ -58,13 +59,14 @@ Options:
-m method -- When used with -c, overrides the default method for
obtaining and building the jail. See poudriere(8) for more
details. Can be one of:
allbsd, ftp-archive, ftp, freebsdci, git, http, null, src=PATH,
svn, svn+file, svn+http, svn+https, svn+ssh, tar=PATH
url=SOMEURL.
allbsd, ftp-archive, ftp, freebsdci, http, url=SOMEURL
git, svn, svn+file, svn+http, svn+https, svn+ssh,
archive=PATH, null, src=PATH, tar=PATH
-P patch -- Specify a patch to apply to the source before building.
-S srcpath -- Specify a path to the source tree to be used.
-D -- Do a full git clone without --depth (default: --depth=1)
-t version -- Version of FreeBSD to upgrade the jail to.
-T args -- Arguments to pass to tar (default: -a)
-U url -- Specify a url to fetch the sources (with method git and/or svn).
-x -- Build and setup native-xtools cross compile tools in jail when
building for a different TARGET ARCH than the host.
Expand Down Expand Up @@ -166,6 +168,40 @@ delete_jail() {
echo " done"
}

archive_jail() {
local version version_vcs arch method mnt timestamp kernel
local archive_tmpdir archive_meta

_jget method ${JAILNAME} method
[ "${method}" = "null" ] && err 1 "Can't archive null jails"
_jget version ${JAILNAME} version
_jget arch ${JAILNAME} arch

_jget kernel ${JAILNAME} kernel || kernel=
_jget mnt ${JAILNAME} mnt || :
_jget timestamp ${JAILNAME} timestamp || timestamp=
_jget version_vcs ${JAILNAME} version_vcs || jversion_vcs=

archive_tmpdir=$(mktemp -d -t poudriere-archive)
archive_meta="${archive_tmpdir}/.jail-archive-meta"

cat > "${archive_meta}" <<-EOF
JAIL_ARCHIVE_VERSION=1
ARCH=${arch}
ARCHIVE_METHOD=${method}
ARCHIVE_TIMESTAMP=${timestamp}
VERSION=${version}
VERSION_VCS=${version_vcs}
KERNEL=${kernel}
EOF

msg "Archiving jail ${JAILNAME}"
tar cf "${ARCHIVE}" ${TAR_ARGS} \
-C "${archive_tmpdir}" .jail-archive-meta \
-C "${mnt}" .
msg "${ARCHIVE} complete"
}

cleanup_new_jail() {
msg "Error while creating jail, cleaning up." >&2
delete_jail
Expand Down Expand Up @@ -786,6 +822,16 @@ install_from_ftp() {
build_native_xtools
}

install_from_archive() {
msg_n "Installing ${VERSION} ${ARCH} from ${ARCHIVE} ..."
tar -xpf ${ARCHIVE} --exclude .jail-archive-meta -C ${JAILMNT}/ || \
err 1 " fail"
echo " done"
if [ -n "${VERSION_VCS}" ]; then
jset ${JAILNAME} version_vcs "${VERSION_VCS}"
fi
}

install_from_tar() {
msg_n "Installing ${VERSION} ${ARCH} from ${TARBALL} ..."
tar -xpf ${TARBALL} -C ${JAILMNT}/ || err 1 " fail"
Expand Down Expand Up @@ -843,6 +889,29 @@ create_jail() {
IFS=${OIFS}
RELEASE="${ALLBSDVER}-JPSNAP/ftp"
;;
archive=*)
ARCHIVE="${METHOD##*=}"
[ -z "${ARCHIVE}" ] && \
err 1 "Must use format -m tar=/path/to/tarball.tar"
case "${ARCHIVE}" in
/*)
;;
*)
# poudrere runs in /tmp
ARCHIVE="${OLDPWD}/${ARCHIVE}"
;;
esac
[ -r "${ARCHIVE}" ] || err 1 "Cannot read file ${ARCHIVE}"
METHOD="${METHOD%%=*}"

archive_tmpdir=$(mktemp -d -t poudriere-archive)
tar xfq "${ARCHIVE}" -C "${archive_tmpdir}" .jail-archive-meta ||
err 1 "Failed to extract .jail-archive-meta from ${ARCHIVE}"
. "${archive_tmpdir}/.jail-archive-meta"
[ -z "${JAIL_ARCHIVE_VERSION}" -o "${JAIL_ARCHIVE_VERSION}" -ne 1 ] &&
err 1 "Unknown JAIL_ARCHIVE_VERSION=${JAIL_ARCHIVE_VERSION}"
FCT=install_from_archive
;;
svn*)
[ -x "${SVN_CMD}" ] || \
err 1 "svn or svnlite not installed. Perhaps you need to 'pkg install subversion'"
Expand Down Expand Up @@ -912,7 +981,11 @@ create_jail() {
if [ -n "${VERSION}" ]; then
jset ${JAILNAME} version ${VERSION}
fi
jset ${JAILNAME} timestamp $(clock -epoch)
if [ "${METHOD}" = "archive" ]; then
jset ${JAILNAME} timestamp ${ARCHIVE_TIMESTAMP}
else
jset ${JAILNAME} timestamp $(clock -epoch)
fi
jset ${JAILNAME} arch ${ARCH}
jset ${JAILNAME} mnt ${JAILMNT}
[ -n "$SRCPATH" ] && jset ${JAILNAME} srcpath ${SRCPATH}
Expand All @@ -921,7 +994,11 @@ create_jail() {
# Wrap the jail creation in a special cleanup hook that will remove the jail
# if any error is encountered
CLEANUP_HOOK=cleanup_new_jail
jset ${JAILNAME} method ${METHOD}
if [ "${METHOD}" = "archive" ]; then
jset ${JAILNAME} method ${ARCHIVE_METHOD}
else
jset ${JAILNAME} method ${METHOD}
fi
[ -n "${FCT}" ] && ${FCT} version_extra

if [ -r "${SRC_BASE}/sys/conf/newvers.sh" ]; then
Expand Down Expand Up @@ -953,7 +1030,7 @@ info_jail() {
local building_started status log
local elapsed elapsed_days elapsed_hms elapsed_timestamp
local now start_time timestamp
local jversion jarch jmethod pmethod mnt fs kernel
local jversion jversion_vcs jarch jmethod pmethod mnt fs kernel

jail_exists ${JAILNAME} || err 1 "No such jail: ${JAILNAME}"

Expand Down Expand Up @@ -1030,32 +1107,43 @@ info_jail() {

get_host_arch ARCH
REALARCH=${ARCH}
START=0
STOP=0
LIST=0
DELETE=0
CREATE=0
RENAME=0
ARCHIVE=
QUIET=0
NAMEONLY=0
INFO=0
UPDATE=0
PTNAME=default
SETNAME=""
TAR_ARG=
XDEV=0
BUILD=0
GIT_DEPTH=--depth=1

while getopts "bBiJ:j:v:a:z:m:nf:M:sdkK:lqcip:r:uU:t:z:P:S:DxC:" FLAG; do
set_command() {
[ -z "${COMMAND}" ] || usage
COMMAND="$1"
}

while getopts "A:bBiJ:j:v:a:z:m:nf:M:sdkK:lqcip:r:uU:t:z:P:S:T:DxC:" FLAG; do
case "${FLAG}" in
A)
set_command archive
ARCHIVE=${OPTARG}
case "${ARCHIVE}" in
/*)
;;
*)
# poudrere runs in /tmp
ARCHIVE="${OLDPWD}/${ARCHIVE}"
;;
esac
;;
b)
BUILD=1
;;
B)
BUILD_PKGBASE=1
;;
i)
INFO=1
set_command info
;;
j)
JAILNAME=${OPTARG}
Expand Down Expand Up @@ -1085,25 +1173,25 @@ while getopts "bBiJ:j:v:a:z:m:nf:M:sdkK:lqcip:r:uU:t:z:P:S:DxC:" FLAG; do
JAILMNT=${OPTARG}
;;
s)
START=1
set_command start
;;
k)
STOP=1
set_command stop
;;
K)
KERNEL=${OPTARG:-GENERIC}
;;
l)
LIST=1
set_command list
;;
c)
CREATE=1
set_command create
;;
C)
CLEANJAIL=${OPTARG}
;;
d)
DELETE=1
set_command delete
;;
p)
PTNAME=${OPTARG}
Expand All @@ -1121,20 +1209,23 @@ while getopts "bBiJ:j:v:a:z:m:nf:M:sdkK:lqcip:r:uU:t:z:P:S:DxC:" FLAG; do
[ -d ${OPTARG} ] || err 1 "No such directory ${OPTARG}"
SRCPATH=${OPTARG}
;;
T)
TAR_ARGS="${OPTARG}"
;;
D)
GIT_DEPTH=""
;;
q)
QUIET=1
;;
u)
UPDATE=1
set_command update
;;
U)
SOURCES_URL=${OPTARG}
;;
r)
RENAME=1;
set_command update
NEWJAILNAME=${OPTARG}
;;
t)
Expand All @@ -1160,7 +1251,7 @@ post_getopts

METHOD=${METHOD:-ftp}
CLEANJAIL=${CLEAN:-none}
if [ -n "${JAILNAME}" -a ${CREATE} -eq 0 ]; then
if [ -n "${JAILNAME}" -a ${COMMAND} != "create" ]; then
_jget ARCH ${JAILNAME} arch || :
_jget JAILFS ${JAILNAME} fs || :
_jget JAILMNT ${JAILNAME} mnt || :
Expand Down Expand Up @@ -1211,11 +1302,17 @@ else
fi


case "${CREATE}${INFO}${LIST}${STOP}${START}${DELETE}${UPDATE}${RENAME}" in
10000000)
case "${COMMAND}" in
archive)
jail_exists ${JAILNAME} || \
err 2 "The jail ${JAILNAME} does not exist"
maybe_run_queued "${saved_argv}"
archive_jail
;;
create)
[ -z "${JAILNAME}" ] && usage JAILNAME
case ${METHOD} in
src=*|null|tar) ;;
archive=*|src=*|null|tar) ;;
*) [ -z "${VERSION}" ] && usage VERSION ;;
esac
jail_exists ${JAILNAME} && \
Expand All @@ -1224,17 +1321,17 @@ case "${CREATE}${INFO}${LIST}${STOP}${START}${DELETE}${UPDATE}${RENAME}" in
check_emulation "${REALARCH}" "${ARCH}"
create_jail
;;
01000000)
info)
[ -z "${JAILNAME}" ] && usage JAILNAME
export MASTERNAME=${JAILNAME}-${PTNAME}${SETNAME:+-${SETNAME}}
_mastermnt MASTERMNT
export MASTERMNT
info_jail
;;
00100000)
list)
list_jail
;;
00010000)
stop)
[ -z "${JAILNAME}" ] && usage JAILNAME
maybe_run_queued "${saved_argv}"
export MASTERNAME=${JAILNAME}-${PTNAME}${SETNAME:+-${SETNAME}}
Expand All @@ -1244,7 +1341,7 @@ case "${CREATE}${INFO}${LIST}${STOP}${START}${DELETE}${UPDATE}${RENAME}" in
msg "Jail ${MASTERNAME} not running, but cleaning up anyway"
jail_stop
;;
00001000)
start)
export SET_STATUS_ON_START=0
[ -z "${JAILNAME}" ] && usage JAILNAME
porttree_exists ${PTNAME} || err 2 "No such ports tree ${PTNAME}"
Expand All @@ -1255,15 +1352,15 @@ case "${CREATE}${INFO}${LIST}${STOP}${START}${DELETE}${UPDATE}${RENAME}" in
MUTABLE_BASE=yes jail_start ${JAILNAME} ${PTNAME} ${SETNAME}
JNETNAME="n"
;;
00000100)
delete)
[ -z "${JAILNAME}" ] && usage JAILNAME
jail_exists ${JAILNAME} || err 1 "No such jail: ${JAILNAME}"
confirm_if_tty "Are you sure you want to delete the jail?" || \
err 1 "Not deleting jail"
maybe_run_queued "${saved_argv}"
delete_jail
;;
00000010)
update)
[ -z "${JAILNAME}" ] && usage JAILNAME
jail_exists ${JAILNAME} || err 1 "No such jail: ${JAILNAME}"
maybe_run_queued "${saved_argv}"
Expand All @@ -1272,7 +1369,7 @@ case "${CREATE}${INFO}${LIST}${STOP}${START}${DELETE}${UPDATE}${RENAME}" in
check_emulation "${REALARCH}" "${ARCH}"
update_jail
;;
00000001)
rename)
[ -z "${JAILNAME}" ] && usage JAILNAME
maybe_run_queued "${saved_argv}"
rename_jail
Expand Down