Add a set of ak-scripts for use by docopt-scripts
authorKevin Klues <klueska@cs.berkeley.edu>
Tue, 3 Nov 2015 15:45:57 +0000 (07:45 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 10 Nov 2015 16:03:27 +0000 (11:03 -0500)
The docopt-scripts tool provides a framework for invoking a collection
of bash scripts through a single command line interface. Its purpose is
to ease the development of these scripts with well-formed usage
semantics from docopt and collect them into a single place for easy
access.

The docopt-scripts tool can be downloaded from here:
https://github.com/google/docopt-scripts

Signed-off-by: Kevin Klues <klueska@cs.berkeley.edu>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
scripts/ak-scripts/ak-code-review.sh [new file with mode: 0644]
scripts/ak-scripts/ak-kill-qemu-monitor.sh [new file with mode: 0644]
scripts/ak-scripts/ak-kill-qemu.sh [new file with mode: 0644]
scripts/ak-scripts/ak-launch-9pserver.sh [new file with mode: 0644]
scripts/ak-scripts/ak-launch-qemu-monitor.sh [new file with mode: 0644]
scripts/ak-scripts/ak-launch-qemu.sh [new file with mode: 0644]
scripts/ak-scripts/ak-rebuild-cross-compiler.sh [new file with mode: 0644]

diff --git a/scripts/ak-scripts/ak-code-review.sh b/scripts/ak-scripts/ak-code-review.sh
new file mode 100644 (file)
index 0000000..fdf070b
--- /dev/null
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2015 Google Inc.
+# Kevin Klues <klueska@cs.berkeley.edu>
+# See LICENSE for details.
+
+# Some global variables
+origin="brho"
+
+function short_description() {
+       echo "Prepare the message body for an akaros code review"
+}
+
+function usage() {
+       echo "Usage:"
+       echo "    ${cmd} [ -h | --help ]"
+       echo "    ${cmd} [ -p ] <base> <remote> [ <head> ]"
+       echo ""
+       echo "Options:"
+       echo "    -h --help           Display this screen and exit"
+       echo "    -p                  Show patch text as well"
+       echo ""
+       echo "Description:"
+       echo "    This tool takes the same parameters as the standard"
+       echo "    git request-pull command but formats the output"
+       echo "    in a more convenient format for akaros code-reviews"
+       echo "    Please copy the contents of the output into an email"
+       echo "    and send it to akaros@googlegroups.com for review"
+}
+
+function gen_request()
+{
+       # Set some local variables
+       local base_sha1=$(git rev-parse ${base})
+       local head_sha1=$(git rev-parse ${head})
+       base_sha1=${base_sha1:0:7}
+       head_sha1=${head_sha1:0:7}
+
+       # Get the text from a git request-pull
+    request=$(git request-pull ${patch} ${base} ${remote} ${head});
+       ret=${?};
+       if [ "${ret}" != "0" ]; then
+               kill -s TERM $TOP_PID
+       else
+               echo "The changes in this request can be viewed online at:"
+               echo "    https://github.com/brho/akaros/compare/${base_sha1}...${head_sha1}"
+               echo ""
+               echo "${request}"
+
+       fi
+}
+
+function main() {
+       # Set so functions can exit from entire program if desired
+       trap "exit 1" TERM
+       export TOP_PID=$$
+
+       # Verify cmd-line options
+       if [ "${head}" = "" ]; then
+               head=$(git rev-parse --abbrev-ref HEAD)
+       fi
+       if [ "${_p}" = "true" ]; then
+               local patch="-p"
+       fi
+
+       gen_request
+}
diff --git a/scripts/ak-scripts/ak-kill-qemu-monitor.sh b/scripts/ak-scripts/ak-kill-qemu-monitor.sh
new file mode 100644 (file)
index 0000000..c7fe9ee
--- /dev/null
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2015 Google Inc.
+# Kevin Klues <klueska@cs.berkeley.edu>
+# See LICENSE for details.
+
+function short_description() {
+       echo "Kill the qemu monitor"
+}
+
+function usage() {
+       echo "Usage: ${cmd}"
+}
+
+function main() {
+       local name="ak-qemu-monitor"
+       screen -X -S ${name} kill
+}
+
diff --git a/scripts/ak-scripts/ak-kill-qemu.sh b/scripts/ak-scripts/ak-kill-qemu.sh
new file mode 100644 (file)
index 0000000..811b378
--- /dev/null
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2015 Google Inc.
+# Kevin Klues <klueska@cs.berkeley.edu>
+# See LICENSE for details.
+
+function short_description() {
+       echo "Kill any Akaros instances of qemu that are running"
+}
+
+function usage() {
+       echo "Usage: ${cmd}"
+}
+
+function main() {
+       local instance=$(ps aux | grep "qemu" | grep akaros-kernel)
+       kill -9 $(echo ${instance} | cut -d" " -f 2)
+}
+
diff --git a/scripts/ak-scripts/ak-launch-9pserver.sh b/scripts/ak-scripts/ak-launch-9pserver.sh
new file mode 100644 (file)
index 0000000..1549eb9
--- /dev/null
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2015 Google Inc.
+# Kevin Klues <klueska@cs.berkeley.edu>
+# See LICENSE for details.
+
+function short_description() {
+       echo "Launch a Go 9pserver for Akaros"
+}
+
+function usage() {
+       echo "Usage:"
+       echo "    ${cmd} -h | --help"
+       echo "    ${cmd} [ --gopath=<gp> ]"
+       echo "    ${cmd//?/ } [ --akaros-9p-root=<mnt> ]"
+       echo "    ${cmd//?/ } [ --ufs-port=<port> ]"
+       echo "    ${cmd//?/ } [ --clear-mount ]"
+       echo "    ${cmd//?/ } [ --rebuild-server ]"
+       echo ""
+       echo "Options:"
+       echo "    -h --help               Display this screen and exit"
+       echo "    --gopath=<gp>           The path to the go workspace"
+       echo "                            [default: \$GOPATH]"
+       echo "    --akaros-9p-root=<mnt>  The location of the akaros 9p mount point"
+       echo "                            [default: \$AKAROS_9P_ROOT]"
+       echo "    --ufs-port=<port>       Port to connect the server on"
+       echo "                            [default: 1025]"
+       echo "    --clear-mount           Clear the 9p mount folder before mounting"
+       echo "    --rebuild-server        Download and rebuild the 9pserver"
+}
+
+function main() {
+       # Check the sanity of our incoming variables
+       check_vars gopath akaros_9p_root ufs_port clear_mount rebuild_server
+       check_dirs gopath akaros_9p_root
+
+       # Set up the go environment variables
+       eval $(go env)
+
+       # If we don't have a server at all, force a rebuild
+       if [ ! -f ${gopath}/bin/ufs ]; then
+               rebuild_server=true
+       fi
+
+       # Get the latest 9p server which supports akaros
+       if [ ${rebuild_server} = true ]; then
+               echo "Downloading and installing the latest supported 9p server"
+               export GOOS=${GOHOSTOS}
+               export GOARCH=${GOHOSTARCH}
+               go get -d -u github.com/rminnich/go9p
+               go get -d -u github.com/rminnich/go9p/ufs
+               go install github.com/rminnich/go9p/ufs
+       fi
+
+       # Clear out the ${akaros_9p_root} directory
+       if [ ${clear_mount} = true ]; then
+               echo "Clearing out ${akaros_9p_root}"
+               rm -rf ${akaros_9p_root}
+       fi
+       mkdir -p ${akaros_9p_root}
+
+       # Kill any old instances of the ufs server on ${ufs_port}
+       local ufs_pid=$(ps aux | grep "ufs" | grep "\-addr=:${ufs_port}" \
+                              | head -1 | awk '{print $2}' )
+       if [ "${ufs_pid}" != "" ]; then
+               echo "Killing old 9p server instance on port=${ufs_port} (pid ${ufs_pid})"
+               echo "${ufs_pid}" | xargs kill
+       fi
+
+       # Start a new ufs instance on ${ufs_port}
+       nohup ${gopath}/bin/ufs -akaros=true -addr=:${ufs_port} \
+                               -root=${akaros_9p_root} >/dev/null 2>&1 &
+       echo "Started 9p server port=${ufs_port} root=${akaros_9p_root} (pid ${!})"
+}
diff --git a/scripts/ak-scripts/ak-launch-qemu-monitor.sh b/scripts/ak-scripts/ak-launch-qemu-monitor.sh
new file mode 100644 (file)
index 0000000..7ad940d
--- /dev/null
@@ -0,0 +1,80 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2015 Google Inc.
+# Kevin Klues <klueska@cs.berkeley.edu>
+# See LICENSE for details.
+
+sleep_cmd="sleep 0xda39a3ee5e6b4b0d3255bfef95601890afd80709"
+welcome_cmd="echo -ne \"Welcome to the qemu monitor!\nPress 'Ctrl-a d' to detach and return to your shell.\n\""
+
+function short_description() {
+       echo "Launch a qemu monitor to attach to a qemu instance"
+}
+
+function usage() {
+       echo "Usage:"
+       echo "    ${cmd} -h | --help"
+       echo "    ${cmd} [ --print-tty-only ]"
+       echo ""
+       echo "Options:"
+       echo "    -h --help         Display this screen and exit"
+       echo "    --print-tty-only  Launch the monitor, print its tty and exit."
+       echo "                      Dont actually enter the monitor."
+}
+
+function get_qemu_monitor_tty() {
+       while [ "${tty_dev}" = "" ]; do
+               local ps_cmd="ps -a -o tty=TTY -o args | grep \"${sleep_cmd}\" | grep -v grep"
+               local ps_info="$(eval "${ps_cmd}")"
+               local tty_dev="$(echo ${ps_info} | cut -d" " -f 1)"
+       done
+       echo "/dev/${tty_dev}"
+}
+
+function main() {
+       # Create the monitor if there isn't one yet
+       local name="ak-qemu-monitor"
+       local list="$(screen -list | grep ${name})"
+       if [ "${list}" == "" ]; then
+               screen -d -m -S ${name} /bin/bash -c "${welcome_cmd};${sleep_cmd}"
+       fi
+
+       # If ${print_tty_only} is set, print the tty and exit
+       if [ "${print_tty_only}" = "true" ]; then
+               get_qemu_monitor_tty
+               exit 0
+       fi
+
+       # Otherwise...
+       # Print some info about using the monitor
+       echo ""
+       echo "You are about to enter the qemu monitor for Akaros!"
+       echo "We use 'screen' to create a tty device to host the monitor."
+       echo "Once attached, you can detach from the monitor at anytime"
+       echo "using the normal screen command:"
+       echo ""
+       echo "    Ctrl-a d"
+       echo ""
+       echo "To reattach from a shell, simply rerun this script:"
+       echo ""
+       echo "    ak launch-qemu-monitor"
+       echo ""
+       echo "While in the monitor, you should be able to run all of"
+       echo "the normal qemu monitor commands. See the following link"
+       echo "for more information:"
+       echo ""
+       echo "    https://en.wikibooks.org/wiki/QEMU/Monitor"
+       echo ""
+
+       # Wait for any key to be pressed
+       echo "Press any key to continue..."
+       (tty_state="$(stty -g)"
+       stty -icanon
+       LC_ALL=C dd bs=1 count=1 > /dev/null 2>&1
+       stty "$tty_state"
+       ) < /dev/tty
+
+       # Attach the monitor
+       screen -d -r ${name}
+}
+
diff --git a/scripts/ak-scripts/ak-launch-qemu.sh b/scripts/ak-scripts/ak-launch-qemu.sh
new file mode 100644 (file)
index 0000000..f5991de
--- /dev/null
@@ -0,0 +1,133 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2015 Google Inc.
+# Kevin Klues <klueska@cs.berkeley.edu>
+# See LICENSE for details.
+
+init_script_default="\"Read from Akaross .config\""
+
+function short_description() {
+       echo "Launch qemu with a running instance of Akaros"
+}
+
+function usage() {
+       echo "Usage:"
+       echo "    ${cmd} -h | --help"
+       echo "    ${cmd} [ --akaros-root=<ak> ]"
+       echo "    ${cmd//?/ } [ --init-script=<script> ]"
+       echo "    ${cmd//?/ } [ --qemu-cmd=<cmd> ]"
+       echo "    ${cmd//?/ } [ --cpu-type=<cpu> ]"
+       echo "    ${cmd//?/ } [ --num-cores=<nc> ]"
+       echo "    ${cmd//?/ } [ --memory-size=<ms> ]"
+       echo "    ${cmd//?/ } [ --network-card=<nc> ]"
+       echo "    ${cmd//?/ } [ --host-port=<hp> ]"
+       echo "    ${cmd//?/ } [ --akaros-port=<ap> ]"
+       echo "    ${cmd//?/ } [ --disable-kvm ]"
+       echo ""
+       echo "Options:"
+       echo "    -h --help               Display this screen and exit"
+       echo "    --akaros-root=<ak>      The path to the root of the akaros tree"
+       echo "                            [default: \$AKAROS_ROOT]"
+       echo "    --init-script=<script>  The path to a custom init script to run after boot"
+       echo "                            [default: ${init_script_default} ]"
+       echo "    --qemu-cmd=<cmd>        The actual qemu command to use"
+       echo "                            [default: qemu-system-x86_64]"
+       echo "    --cpu-type=<cpu>        The type of cpu to launch qemu with"
+       echo "                            [default: kvm64,+vmx]"
+       echo "    --num-cores=<nc>        The number of cores to launch qemu with"
+       echo "                            [default: 8]"
+       echo "    --memory-size=<ms>      The amount of memory to launch qemu with (kB)"
+       echo "                            [default: 4096]"
+       echo "    --network-card=<nc>     The network card to launch qemu qith"
+       echo "                            [default: e1000]"
+       echo "    --host-port=<hp>        The host port to forward network traffic"
+       echo "                            [default: 5555]"
+       echo "    --akaros-port=<hp>      The akaros port to receive network traffic"
+       echo "                            [default: 5555]"
+       echo "    --disable-kvm           Disable kvm for qemu"
+}
+
+function main() {
+       # Set these command line arguments before invoking main
+       # Check the sanity of our environment variables
+       check_vars akaros_root qemu_cmd init_script cpu_type num_cores \
+                  memory_size network_card host_port akaros_port
+       check_dirs akaros_root
+       check_execs qemu_cmd
+       if [ "\"${init_script}\"" != "${init_script_default}" ]; then
+               check_files init_script
+               local init_script_set="true"
+       fi
+
+       # Set some local variables
+       local akaros_bin=${akaros_root}/kern/kfs/bin
+       local akaros_kernel=${akaros_root}/obj/kern/akaros-kernel
+       local akaros_config=${akaros_root}/.config
+       local akaros_config_backup=${akaros_root}/.config.backup
+       local akinit_script="/bin/ak-init.sh"
+       local akinit_script_path=${akaros_root}/kern/kfs/${akinit_script}
+       local qemu_network="-net nic,model=${network_card} \
+                           -net user,hostfwd=tcp::${host_port}-:${akaros_port}"
+
+       # Launch the monitor if not launched yet and set the monitor tty
+       local monitor_tty="$(ak launch-qemu-monitor --print-tty-only)"
+       if [ "${monitor_tty}" != "" ]; then
+               local qemu_monitor="-monitor ${monitor_tty}"
+       fi
+
+       # Output a warning if we are trying to enable kvm for qemu, but we are not
+       # part of the kvm group
+       if [ "${disable_kvm}" == "false" ]; then
+               groups ${USER} | grep &>/dev/null '\bkvm\b'
+               if [ "${?}" != "0" ]; then
+                       echo "You are not part of the kvm group!"
+                       echo "    This may cause problems with running qemu with kvm enabled."
+                       echo "    To disable kvm, rerun this script with --disable-kvm."
+               fi
+               local qemu_kvm="-enable-kvm"
+       fi
+
+       # Make a backup of ${akaros_config} and set the init script in it
+       if [ "${init_script_set}" == "true" ]; then
+               echo "Setting custom init script"
+               cp ${akaros_config} ${akaros_config_backup}
+               cp ${init_script} ${akinit_script_path}
+               if [ "$(grep 'CONFIG_RUN_INIT_SCRIPT=' ${akaros_config})" = "" ]; then
+                       echo "CONFIG_RUN_INIT_SCRIPT=y" >> ${akaros_config}
+                       echo "CONFIG_INIT_SCRIPT_PATH_AND_ARGS=\"${akinit_script}\"" >> ${akaros_config}
+               else
+                       sed -ie 's#CONFIG_INIT_SCRIPT_PATH_AND_ARGS=.*#CONFIG_INIT_SCRIPT_PATH_AND_ARGS="'${akinit_script}'"#' ${akaros_config}
+               fi
+       fi
+
+       # Rebuild akaros
+       echo "Rebuilding akaros"
+       cd ${akaros_root}
+       touch ${akaros_config}
+       make -j
+       cd - > /dev/null
+
+       # Restore the original ${akaros_config} and delete the init script
+       if [ "${init_script_set}" == "true" ]; then
+               mv ${akaros_config_backup} ${akaros_config}
+               rm ${akinit_script_path}
+       fi
+
+       # Rebuild akaros test and libs
+       echo "Rebuilding tests and libs"
+       cd ${akaros_root}
+       make -j install-libs
+       make -j tests
+       make fill-kfs
+       cd - > /dev/null
+
+       # Launching qemu
+       echo "Launching qemu"
+       local stty_state=$(stty -g)
+       stty raw
+       ${qemu_cmd} -s ${qemu_kvm} ${qemu_network} ${qemu_monitor} -cpu ${cpu_type} \
+                   -smp ${num_cores} -m ${memory_size} -kernel ${akaros_kernel} \
+                   -nographic
+       stty ${stty_state}
+}
+
diff --git a/scripts/ak-scripts/ak-rebuild-cross-compiler.sh b/scripts/ak-scripts/ak-rebuild-cross-compiler.sh
new file mode 100644 (file)
index 0000000..af0d0bd
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2015 Google Inc.
+# Kevin Klues <klueska@cs.berkeley.edu>
+# See LICENSE for details.
+
+inst_dir_default="\"\${ARCH}_INSTDIR based on the configured architecture in akaros_root\""
+
+function short_description() {
+       echo "Rebuild the Akaros cross compiler and all of its dependencies"
+}
+
+function usage() {
+       echo "Usage:"
+       echo "    ${cmd} -h | --help"
+       echo "    ${cmd} [ --akaros-root=<ak> ]"
+       echo "    ${cmd//?/ } [ --inst-dir=<dir> ]"
+       echo ""
+       echo "Options:"
+       echo "    -h --help                Display this screen and exit"
+       echo "    --akaros-root=<ak>       The path to the root of the akaros tree"
+       echo "                             [default: \$AKAROS_ROOT]"
+       echo "    --inst-dir=<dir>         The installation path of the cross compiler"
+       echo "                             [default: ${inst_dir_default} ]"
+}
+
+function main() {
+       # Check the sanity of our incoming variables
+       check_vars akaros_root inst_dir
+       check_dirs akaros_root
+
+       # Set some local variables
+       local arch="$(basename $(readlink ${akaros_root}/kern/include/arch))"
+       if [ "${arch}" = "x86" ]; then
+               arch="x86_64"
+       fi
+       local make_jobs=$(expr `cat /proc/cpuinfo | grep processor | wc -l` - 1)
+
+       # Set real default of $inst_dir
+       if [ "${inst_dir}" != "${inst_dir_default}" ]; then
+               inst_dir="$(eval echo \$${arch^^}_INSTDIR)"
+       fi
+
+       # Rebuild the cross compiler
+       cd "${akaros_root}"
+       eval ${arch^^}_INSTDIR=${inst_dir} \
+               make -j ${make_jobs} xcc-upgrade-from-scratch
+       cd - > /dev/null
+}