diff --git a/README.md b/README.md index 00409a7..9b67fe7 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ close to running containers. [krunvm] creates and starts VMs based on the multi-platform OCI images created for this project -- [ubuntu] (default) or [fedora]. +![Demo](./demo/demo.gif) + [self]: https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners [runners]: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners [krunvm]: https://github.com/containers/krunvm diff --git a/demo/README.md b/demo/README.md new file mode 100644 index 0000000..47525d7 --- /dev/null +++ b/demo/README.md @@ -0,0 +1,26 @@ +# Demo with terminalizer + +## Recording + +Provided you have [terminalizer] installed, run the following from the top +directory of this repository. + +```bash +terminalizer record demo/demo.yml --config demo/config.yml +``` + +## Verifying + +Once done, use the [`play`][play] sub-command to verify your recording. You +might want to remove output lines from the YAML, alternatively change the pace. + +## Render + +Finally, run the following command to generate the animated GIF + +```bash +terminalizer render demo/demo.yml --output demo/demo.gif +``` + + [terminalizer]: https://github.com/faressoft/terminalizer + [play]: https://github.com/faressoft/terminalizer?tab=readme-ov-file#play diff --git a/demo/config.yml b/demo/config.yml new file mode 100644 index 0000000..22ceaba --- /dev/null +++ b/demo/config.yml @@ -0,0 +1,107 @@ +# Specify a command to be executed +# like `/bin/bash -l`, `ls`, or any other commands +# the default is bash for Linux +# or powershell.exe for Windows +command: ./demo/demo.sh + +# Specify the current working directory path +# the default is the current working directory path +cwd: null + +# Export additional ENV variables +env: + recording: true + +# Explicitly set the number of columns +# or use `auto` to take the current +# number of columns of your shell +cols: 180 + +# Explicitly set the number of rows +# or use `auto` to take the current +# number of rows of your shell +rows: 40 + +# Amount of times to repeat GIF +# If value is -1, play once +# If value is 0, loop indefinitely +# If value is a positive number, loop n times +repeat: 0 + +# Quality +# 1 - 100 +quality: 95 + +# Delay between frames in ms +# If the value is `auto` use the actual recording delays +frameDelay: auto + +# Maximum delay between frames in ms +# Ignored if the `frameDelay` isn't set to `auto` +# Set to `auto` to prevent limiting the max idle time +maxIdleTime: auto + +# The surrounding frame box +# The `type` can be null, window, floating, or solid` +# To hide the title use the value null +# Don't forget to add a backgroundColor style with a null as type +frameBox: + type: floating + title: GitHub Runner in KrunVM + style: + border: 0px black solid + # boxShadow: none + # margin: 0px + +# Add a watermark image to the rendered gif +# You need to specify an absolute path for +# the image on your machine or a URL, and you can also +# add your own CSS styles +watermark: + imagePath: null + style: + position: absolute + right: 15px + bottom: 15px + width: 100px + opacity: 0.9 + +# Cursor style can be one of +# `block`, `underline`, or `bar` +cursorStyle: block + +# Font family +# You can use any font that is installed on your machine +# in CSS-like syntax +fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace" + +# The size of the font +fontSize: 12 + +# The height of lines +lineHeight: 1 + +# The spacing between letters +letterSpacing: 0 + +# Theme +theme: + background: "transparent" + foreground: "#afafaf" + cursor: "#c7c7c7" + black: "#232628" + red: "#fc4384" + green: "#b3e33b" + yellow: "#ffa727" + blue: "#75dff2" + magenta: "#ae89fe" + cyan: "#708387" + white: "#d5d5d0" + brightBlack: "#626566" + brightRed: "#ff7fac" + brightGreen: "#c8ed71" + brightYellow: "#ebdf86" + brightBlue: "#75dff2" + brightMagenta: "#ae89fe" + brightCyan: "#b1c6ca" + brightWhite: "#f9f9f4" diff --git a/demo/demo-magic/demo-magic.sh b/demo/demo-magic/demo-magic.sh index 5efbe62..181fd3b 100755 --- a/demo/demo-magic/demo-magic.sh +++ b/demo/demo-magic/demo-magic.sh @@ -88,13 +88,13 @@ function p() { fi # render the prompt - x=$(PS1="$DEMO_PROMPT" "$BASH" --norc -i &1 | sed -n '${s/^\(.*\)exit$/\1/p;}') + x=$(PS1="$DEMO_PROMPT" "$BASH" --norc -i &1 | sed -n 's/^\(.*\)exit$/\1/p;') # show command number is selected if $SHOW_CMD_NUMS; then - printf "[$((++C_NUM))] $x" + printf "[$((++C_NUM))] %s" "$x" else - printf "$x" + printf "%s" "$x" fi # wait for the user to press a key before typing the command @@ -105,7 +105,7 @@ function p() { if [[ -z $TYPE_SPEED ]]; then echo -en "$cmd" else - echo -en "$cmd" | pv -qL $[$TYPE_SPEED+(-2 + RANDOM%5)]; + echo -en "$cmd" | pv -qL $((TYPE_SPEED+(-2 + RANDOM%5))); fi # wait for the user to press a key before moving on @@ -151,20 +151,20 @@ function pei { ## function cmd() { # render the prompt - x=$(PS1="$DEMO_PROMPT" "$BASH" --norc -i &1 | sed -n '${s/^\(.*\)exit$/\1/p;}') - printf "$x\033[0m" - read command + x=$(PS1="$DEMO_PROMPT" "$BASH" --norc -i &1 | sed -n 's/^\(.*\)exit$/\1/p;') + printf "%s\033[0m" "$x" + read -r command run_cmd "${command}" } -function run_cmd() { - function handle_cancel() { - printf "" - } +function handle_cancel() { + printf "" +} +function run_cmd() { trap handle_cancel SIGINT stty -echoctl - eval $@ + eval "$*" stty echoctl trap - SIGINT } @@ -216,6 +216,11 @@ while getopts ":dhncw:" opt; do w) PROMPT_TIMEOUT=$OPTARG ;; + *) + echo "Invalid option: -$OPTARG" >&2 + usage + exit 1 + ;; esac done diff --git a/demo/demo.gif b/demo/demo.gif new file mode 100644 index 0000000..5a162ac Binary files /dev/null and b/demo/demo.gif differ diff --git a/demo/demo.sh b/demo/demo.sh index d6340ab..3461475 100755 --- a/demo/demo.sh +++ b/demo/demo.sh @@ -13,6 +13,9 @@ fi clear -pe "# For the sake of the asciicast: PAT is present in RUNNER_PAT environment variable" -pe "# -r 1: to run once only, the default is to run forever" -pe "./orchestrator.sh -v -- -r 1 -p efrecon/gh-runner-krunvm" +pei "# Let's start one (artificially short-lived) runner for this repository" +pei "# A PAT is present in the environment variable RUNNER_PAT" +pei "# Just for the demo, we will use two seldom used options to show teardown" +pei "# -k 40: to run for 40 seconds only, the default is to run forever, until a job is picked" +pei "# -r 1: to run once only, the default is to create ephemeral runners forever" +pei "./orchestrator.sh -v -- -r 1 -k 40 -p efrecon/gh-runner-krunvm" diff --git a/runner.sh b/runner.sh index e2c1625..068a052 100755 --- a/runner.sh +++ b/runner.sh @@ -112,11 +112,14 @@ RUNNER_REPEAT=${RUNNER_REPEAT:-"-1"} # Secret to be used to request for loop end. Good default is a random string. RUNNER_SECRET=${RUNNER_SECRET:-"$(random_string)"} +# Number of seconds after which to terminate (empty for never, the good default) +RUNNER_TERMINATE=${RUNNER_TERMINATE:-""} + # shellcheck disable=SC2034 # Used in sourced scripts KRUNVM_RUNNER_DESCR="Create runners forever using krunvm" -while getopts "c:d:D:g:G:i:l:L:m:M:p:r:s:S:T:u:Uvh-" opt; do +while getopts "c:d:D:g:G:i:l:L:m:M:p:k:r:s:S:T:u:Uvh-" opt; do case "$opt" in c) # Number of CPUs to allocate to the VM RUNNER_CPUS="$OPTARG";; @@ -144,6 +147,8 @@ while getopts "c:d:D:g:G:i:l:L:m:M:p:r:s:S:T:u:Uvh-" opt; do fi;; p) # Principal to authorise the runner for, name of repo, org or enterprise RUNNER_PRINCIPAL="$OPTARG";; + k) # Kill and terminate after this many seconds + RUNNER_TERMINATE="$OPTARG";; r) # Number of times to repeat the runner loop RUNNER_REPEAT="$OPTARG";; s) # Scope of the runner, one of repo, org or enterprise @@ -268,6 +273,10 @@ EOF RUNNER_PID=$! eval "$optstate"; # Restore options verbose "Started microVM '${RUNNER_PREFIX}-$_id' with PID $RUNNER_PID" + if [ -n "$RUNNER_TERMINATE" ]; then + verbose "Terminating runner in $RUNNER_TERMINATE seconds" + sleep "$RUNNER_TERMINATE" && cleanup & + fi wait "$RUNNER_PID" RUNNER_PID= } @@ -280,8 +289,10 @@ vm_delete() { warning "Removing isolation environment ${RUNNER_ENVIRONMENT}/${1}.env" rm -f "${RUNNER_ENVIRONMENT}/${1}.env" fi - verbose "Removing microVM '${RUNNER_PREFIX}-$1'" - run_krunvm delete "${RUNNER_PREFIX}-$1" + if run_krunvm list | grep -qE "^${RUNNER_PREFIX}-$1"; then + verbose "Removing microVM '${RUNNER_PREFIX}-$1'" + run_krunvm delete "${RUNNER_PREFIX}-$1" + fi } vm_terminate() { @@ -313,10 +324,10 @@ vm_terminate() { cleanup() { trap '' EXIT - if [ -n "$RUNNER_PID" ]; then + if [ -n "${RUNNER_PID:-}" ]; then vm_terminate fi - if [ -n "$RUNNER_ID" ]; then + if [ -n "${RUNNER_ID:-}" ]; then vm_delete "$RUNNER_ID" fi }