diff options
Diffstat (limited to 'imgpkg.write')
-rwxr-xr-x | imgpkg.write | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/imgpkg.write b/imgpkg.write new file mode 100755 index 00000000..c911c89b --- /dev/null +++ b/imgpkg.write @@ -0,0 +1,142 @@ +#!/bin/sh +# Copyright (C) 2014 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# =*= License: GPL-2 =*= +# +# +# This is a write extension for making a package that can be used to +# install the produced system. Ideally we'd instead have Baserock +# everywhere to do the deployment, but we need to support this workflow +# until that is possible. +# +# It gets configured with a script templates that get filled in with the +# paths to the rootfs tarball as @@ROOTFS_TAR_PATH@@, script directory as +# @@SCRIPT_DIR@@ and copied boot-files as @@IMAGE_DIR@@. +# +# Scripts to include are specified as a relative path to your morphologies +# repository, separated by : characters in the INCLUDE_SCRIPTS variable. +# If another separator is convenient, it can be specified in the +# INCLUDE_SCRIPTS_SEPARATOR variable, which has the same semantics as the +# shell IFS variable. +# +# Other files needed to create the disk image, such as bootloader image +# files can be specified in BOOTLOADER_BLOBS, relative to the root of the +# rootfs, separated with similar rules to INCLUDE_SCRIPTS. +# +# The name of the rootfs tarball, the scripts subdirectory and the +# bootloader blobs subdirectory can be changed with the ROOTFS_TAR, +# SCRIPT_SUBDIR and IMAGE_SUBDIR variables, but the default should be +# sufficient. +# +# The compression of the rootfs tarball, and the package tarball can be +# specified by specifying a shell command that reads the uncompressed +# tarball from stdin and writes to stdout in the ROOTFS_COMPRESS and +# OUTPUT_COMPRESS variables. + +set -eu + +die(){ + echo "$@" >&2 + exit 1 +} + +warn(){ + echo "$@" >&2 +} + +info(){ + echo "$@" >&2 +} + +shellescape(){ + echo "'$(echo "$1" | sed -e "s/'/'\\''/g")'" +} + +sedescape(){ + # Escape the passed in string so it can be safely interpolated into + # a sed expression as a literal value. + echo "$1" | sed -e 's/[\/&]/\\&/g' +} + +ROOTDIR="$1" +OUTPUT_TAR="$2" +td="$(mktemp -d)" +IMAGE_SUBDIR="${IMAGE_SUBDIR-image_files}" +SCRIPT_SUBDIR="${SCRIPT_SUBDIR-tools}" +ROOTFS_TAR="${ROOTFS_TAR-rootfs.tar}" + +install_script(){ + local source_file="$1" + local output_dir="$2" + local target_file="$output_dir/$SCRIPT_SUBDIR/$(basename "$source_file" .in)" + local find_script_dir='"$(readlink -f "$(dirname "$0")")"' + local image_dir="$find_script_dir/../$(shellescape "$IMAGE_SUBDIR")" + local rootfs_tar_path="$image_dir/$(shellescape "$ROOTFS_TAR")" + sed -e "s/@@SCRIPT_DIR@@/$(sedescape "$find_script_dir")/g" \ + -e "s/@@IMAGE_DIR@@/$(sedescape "$image_dir")/g" \ + -e "s/@@ROOTFS_TAR_PATH@@/$(sedescape "$rootfs_tar_path")/g" \ + "$source_file" \ + | install -D -m 755 /proc/self/fd/0 "$target_file" +} + +install_scripts(){ + local output_dir="$1" + ( + IFS="${INCLUDE_SCRIPTS_SEPATATOR-:}" + for script in $INCLUDE_SCRIPTS; do + local script_path="$(pwd)/$script" + if [ ! -e "$script_path" ]; then + warn Script "$script" not found, ignoring + continue + fi + install_script "$script" "$output_dir" + done + ) +} + +install_bootloader_blobs(){ + local output_dir="$1" + local image_dir="$output_dir/$IMAGE_SUBDIR" + ( + IFS="${BOOTLOADER_BLOBS_SEPATATOR-:}" + for blob in $BOOTLOADER_BLOBS; do + local blob_path="$ROOTDIR/$blob" + if [ ! -e "$blob_path" ]; then + warn Bootloader blob "$blob" not found, ignoring + continue + fi + install -D -m644 "$blob_path" "$image_dir/$(basename "$blob_path")" + done + ) +} + +output_dir="$(basename "$OUTPUT_TAR")" +for ext in .xz .bz2 .gzip .gz .tgz .tar; do + output_dir="${output_dir%$ext}" +done + +info Installing scripts +install_scripts "$td/$output_dir" + +info Installing bootloader blobs +install_bootloader_blobs "$td/$output_dir" + +info Writing rootfs tar to "$IMAGE_SUBDIR/$ROOTFS_TAR" +tar -C "$ROOTDIR" -c . \ +| sh -c "${ROOTFS_COMPRESS-cat}" >"$td/$output_dir/$IMAGE_SUBDIR/$ROOTFS_TAR" + +info Writing image package tar to "$OUTPUT_TAR" +tar -C "$td" -c "$output_dir" | sh -c "${OUTPUT_COMPRESS-cat}" >"$OUTPUT_TAR" |