#!/usr/bin/env bash # 2018 Luke Shumaker declare -r NAME=osi-run declare -r VERSION=20180812 set -euE source "${BASH_SOURCE[0]%/*}/lib/osi.sh" main() { local arg_mode=outside local arg_mountpoint= local arg_image= local arg_qemu=( qemu-system-x86_64 -machine accel=kvm -m 512 ) local args if ! args="$(getopt -n "${0##*/}" -o hV -l inside:,help,version -- "$@")"; then arg_mode=error else eval "args=($args)" set -- "${args[@]}" while true; do case "$1" in --inside) shift; arg_mode=inside; arg_mountpoint=$1; shift;; -V|--version) shift; arg_mode=version;; -h|--help) shift; arg_mode=usage;; --) shift; break;; *) error 1 'Internal error. The programmer writing this tool screwed up.';; esac done case "$arg_mode" in outside|inside) if (( $# != 1 )); then if (( $# == 0 )); then error 0 "Expected 1 positional argument, got none" else error 0 "Expected 1 positional argument, got %d: %s" "$#" "${@@Q}" fi arg_mode=error else arg_image=$1 fi ;; esac fi case "$arg_mode" in error) print "Try '%q --help' for more information" "${0##*/}" >&2; return 2;; version) print "%s (notsystemd) %s" "$NAME" "$VERSION" return 0 ;; usage) print 'Usage: %s [OPTIONS] FILENAME.img < SCRIPT.sh' "${0##*/}" print 'Operating System Image: Run Script' echo print 'OPTIONS:' # --inside is internal-only; undocumented print ' -h, --help display this help' print ' -V, --version output version information' return 0 ;; # main code starts here # # We get a little tricky with umount/mount, instead of # just calling osi-mount twice, because # - want to escalate privileges *only once* # - we want osi-mount to be the *only* command we # escalate privileges for outside) arg_mountpoint=$(mktemp -dt -- "${0##*/}.XXXXXXXXXX") trap "rmdir -- ${arg_mountpoint@Q}" EXIT sudo -- ./osi-mount "$arg_image" "$arg_mountpoint" "${BASH_SOURCE[0]}" --inside="$arg_mountpoint" "${args[@]}" ;; inside) # just keep reading... needs_sudo install -Dm755 /dev/stdin "$arg_mountpoint/etc/osi-run" umount "$arg_mountpoint" sudo -u "#${SUDO_UID}" -- "${qemu[@]}" -drive media=disk,format=raw,if=virtio,file="$arg_image" mount "$arg_image" "$arg_mountpoint" cat "$arg_mountpoint/var/log/osi-run.out" return "$(cat "$arg_mountpoint/var/log/osi-run.status")" ;; *) error 1 'Internal error. The programmer writing this tool screwed up.';; esac } main "$@"