-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #228 from replicatedhq/instruqt-feature-tmux-template
Provides a template for preserving the shell across challenges
- Loading branch information
Showing
14 changed files
with
466 additions
and
0 deletions.
There are no files selected for viewing
69 changes: 69 additions & 0 deletions
69
instruqt/shared-env-template/01-getting-to-know-the-template/assignment.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
--- | ||
slug: getting-to-know-the-template | ||
id: ofusufdxjhva | ||
type: challenge | ||
title: Getting to Know the Template | ||
teaser: Some tips and tricks for using this template | ||
notes: | ||
- type: text | ||
contents: Let's learn about this template | ||
tabs: | ||
- title: Shell | ||
type: terminal | ||
hostname: shell | ||
difficulty: basic | ||
timelimit: 300 | ||
--- | ||
|
||
👋 Introduction | ||
=============== | ||
|
||
This template is a baseline for labs that need to persist their shell | ||
environment across challenges. This may be because you as the learner | ||
to set some environment variables, or because they've started a long | ||
running process, or just to make it feel more like the real world | ||
where they're doing everything in the same shell session. | ||
|
||
As a cool side-effect, you can also use this template if you want | ||
to interact with the contents of the learner's shell session. The | ||
track uses `tmux` to persist the shell, and with that comes the | ||
opportunity to read the content of the entire `tmux` pane. That | ||
content includes the commands the learner types and the output of | ||
those commands. This can come in very handy in lifecycle scripts, as | ||
can `tmux`'s ability to send keystrokes into the session. | ||
|
||
|
||
🔤 Basics | ||
========= | ||
|
||
You don't really have to do anything special to use this template. | ||
It's configured to start a shell container and a single node Kubernetes | ||
cluster. The shell uses our Instruqt shell image, and runs a `tmux` | ||
session named `shell`. In that sesion it starts a login shell as the | ||
user `replicant` using `su`. | ||
|
||
The first challenge will create the session, and additional challenges | ||
will connect to the existing session. This is enabled by following | ||
command which is the `shell` specified in `config.yml` for the `Shell` | ||
sandbox. | ||
|
||
```yaml | ||
- name: shell | ||
image: gcr.io/kots-field-labs/shell:instruqt-feature-tmux-template | ||
shell: tmux new-session -A -s shell su - replicant | ||
``` | ||
This one command will either create a new session named `shell` running | ||
`su - replicant`, or join an existing session named `shell`. The existing | ||
session will continue with whatever command it was running in the prior | ||
challenge which may just be `replicant`'s shell. | ||
|
||
🧪 Try It | ||
========= | ||
|
||
Let's set an environment variable in this challenge so we can take | ||
advantage of it in the next one. | ||
|
||
```shell | ||
export THIS="the way" | ||
``` |
15 changes: 15 additions & 0 deletions
15
instruqt/shared-env-template/01-getting-to-know-the-template/check-shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
|
||
# save the entire session to check user inputs and outputs | ||
tmux capture-pane -t shell -S - | ||
SESSION=$(tmux save-buffer -) | ||
|
||
# check for disconnection | ||
if ! grep -qE 'THIS=[A-Za-z "]+' <(echo ${SESSION}) ; then | ||
fail-message 'Please try it out by setting the environment variable `$THIS`' | ||
exit 1 | ||
fi | ||
|
10 changes: 10 additions & 0 deletions
10
instruqt/shared-env-template/01-getting-to-know-the-template/cleanup-shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
|
||
# clear the tmux pane and scrollback to look like a fresh shell | ||
tmux clear-history -t shell | ||
tmux send-keys -t shell clear ENTER | ||
|
||
exit 0 |
24 changes: 24 additions & 0 deletions
24
instruqt/shared-env-template/01-getting-to-know-the-template/setup-shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
|
||
HOME_DIR=/home/replicant | ||
|
||
# Wait for Instruqt bootstrap to be complete | ||
while [ ! -f /opt/instruqt/bootstrap/host-bootstrap-completed ] | ||
do | ||
echo "Waiting for Instruqt to finish booting the VM" | ||
sleep 1 | ||
done | ||
|
||
# Display PARTICIPANT_ID info for Vendor Portal | ||
cat<<SCRIPT >> ${HOME_DIR}/.bashrc | ||
show_credentials () { | ||
echo Credentials for https://vendor.replicated.com | ||
echo Username: $INSTRUQT_PARTICIPANT_ID@replicated-labs.com | ||
echo Password: $INSTRUQT_PARTICIPANT_ID | ||
} | ||
show_credentials | ||
SCRIPT |
18 changes: 18 additions & 0 deletions
18
instruqt/shared-env-template/01-getting-to-know-the-template/solve-shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
|
||
### Assure the tmux session exists | ||
# | ||
# In a test scenario Instuqt does not run the user shell for the | ||
# challenge, which means the tmux session is never established. We | ||
# need to session for the solve scripts for other challenges to | ||
# succeed, so let's create it here. | ||
# | ||
|
||
if ! tmux has-session -t shell ; then | ||
tmux new-session -d -s shell su - replicant | ||
fi | ||
|
||
tmux send-keys -t shell export SPACE 'THIS="the way"' ENTER |
83 changes: 83 additions & 0 deletions
83
instruqt/shared-env-template/02-using-the-template/assignment.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
--- | ||
slug: using-the-template | ||
id: zkvoizkrqisu | ||
type: challenge | ||
title: Using the Template | ||
teaser: Some guidance on using the template | ||
notes: | ||
- type: text | ||
contents: How and Why to Use This Template | ||
tabs: | ||
- title: Shell | ||
type: terminal | ||
hostname: shell | ||
difficulty: basic | ||
timelimit: 300 | ||
--- | ||
|
||
✨ Uses | ||
======= | ||
|
||
## Environment Variables | ||
|
||
Only one shell runs across all challenges. This means the values of | ||
environment variables persist from challenge to challenge without the | ||
user setting them into their `.bashrc`. | ||
|
||
## Long Running Commands | ||
|
||
If a challenge needs to end with long running command (for example | ||
downloading an airgap bundle or starting a kURL install), tell the user | ||
they can click **Check** and leave the comamnd running. When the next | ||
challenge starts then their shell will look the same and the command | ||
will still be running (unless it happened to finish during the Cleanup | ||
and Check scripts). | ||
|
||
🔄 Lifecycle Scripts | ||
==================== | ||
|
||
Lifecycle scripts can take advantage of `tmux` to read and write from | ||
the learner's session. This is useful in Check scripts, for example, | ||
to read what the user has typed and what the output was from those | ||
commands. It also means that Setup, Cleanup, and Solve scripts can | ||
type into the users shell to run commands. | ||
|
||
Here are a couple of `tmux` commands to be aware of to interact with | ||
the session: | ||
|
||
`tmux capture-pane` | ||
: This command the history of what's been done in the learner's | ||
shell so you can intertact with it, for example to test whether | ||
they typed the commands you expected | ||
|
||
`tmux save-buffer` | ||
: After you've captured what the learner has done, you can use the | ||
`save-buffer` command to access it. The combination of the two is | ||
useful in Check scripts | ||
|
||
`tmux send-keys` | ||
: Allows you to send keystrokes to the learner's shell. You have to | ||
be explicit about charaters like `SPACE` and `ENTER` so that they | ||
are sent to. This can be great for Solve scripts. | ||
|
||
`tmux clear-histry` | ||
: Clears the scrollback history (not the shell history) to keep | ||
what's captured by `capture-pane` nice and fresh. | ||
|
||
🧪 Did It Work? | ||
=============== | ||
|
||
Remember that variable we set in the last step? Let's make sure it | ||
stuck around like we expected. | ||
|
||
``` | ||
echo $THIS | ||
``` | ||
|
||
It should have, so you should see | ||
|
||
```text | ||
replicant@shell:~$ echo $THIS | ||
the way | ||
replicant@shell:~$ | ||
``` |
15 changes: 15 additions & 0 deletions
15
instruqt/shared-env-template/02-using-the-template/check-shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
|
||
# save the entire session to check user inputs and outputs | ||
tmux capture-pane -t shell -S - | ||
SESSION=$(tmux save-buffer -) | ||
|
||
# check for disconnection | ||
if ! grep -qE 'echo' <(echo ${SESSION}) ; then | ||
fail-message 'Please make sure you can still access `$THIS`' | ||
exit 1 | ||
fi | ||
|
11 changes: 11 additions & 0 deletions
11
instruqt/shared-env-template/02-using-the-template/cleanup-shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/bin/sh | ||
# | ||
# This script runs when the platform cleanup the challenge. | ||
# | ||
# The platform determines if the script was successful using the exit code of this | ||
# script. If the exit code is not 0, the script fails. | ||
# | ||
|
||
echo "This is the cleanup script" | ||
|
||
exit 0 |
18 changes: 18 additions & 0 deletions
18
instruqt/shared-env-template/02-using-the-template/solve-shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
|
||
### Assure the tmux session exists | ||
# | ||
# In a test scenario Instuqt does not run the user shell for the | ||
# challenge, which means the tmux session is never established. We | ||
# need to session for the solve scripts for other challenges to | ||
# succeed, so let's create it here. | ||
# | ||
|
||
if ! tmux has-session -t shell ; then | ||
tmux new-session -d -s shell su - replicant | ||
fi | ||
|
||
tmux send-keys -t shell echo SPACE '$THIS' ENTER |
111 changes: 111 additions & 0 deletions
111
instruqt/shared-env-template/03-tips-and-tricks/assignment.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
--- | ||
slug: tips-and-tricks | ||
id: 8axg0ijvq0ru | ||
type: challenge | ||
title: Tips and Tricks | ||
teaser: Some tips and recomended defaults | ||
notes: | ||
- type: text | ||
contents: Making the most of this template | ||
tabs: | ||
- title: Shell | ||
type: terminal | ||
hostname: shell | ||
difficulty: basic | ||
timelimit: 300 | ||
--- | ||
|
||
💡 Tips and Tricks | ||
================== | ||
|
||
## Checking What Happened | ||
|
||
As mentioned above, you can capture what went on during a challenge | ||
using a pair of `tmux` commands. Here's an example of how you might | ||
capture the entire history of a challenge: | ||
|
||
```shell | ||
# save the entire session to check user inputs and outputs | ||
tmux capture-pane -t shell -S - | ||
SESSION=$(tmux save-buffer -) | ||
``` | ||
|
||
You may want to capture a subset of what was done. In this example, | ||
we get the last ten lines. | ||
|
||
```shell | ||
# save the last _LINES_ lines to check inputs and outputs | ||
LINES=10 | ||
HEIGHT=$(tmux list-panes -F "#{pane_height}") | ||
SESSION=$(tmux capture-pane -t shell -S $(expr $HEIGHT - $LINES) -p) | ||
``` | ||
|
||
In either case, you can use `grep` or either shell commands to examine | ||
`SESSION` and see if they user followed you instructions. | ||
|
||
## Entering Commands in Solve | ||
|
||
Your solve command can run as usual and not interact with the learner's | ||
shell. That's the recommended approach for most challenges. Some solve | ||
scripts can be done that way, for example setting environment variables | ||
you'll need in another challenge. In that case, you can use `send-keys` | ||
in your solve script to change the environment. | ||
|
||
```shell | ||
tmux send-keys -t shell export SPACE REPLICATED_APP=wordpress-civet ENTER | ||
``` | ||
|
||
Note that since the shell isn't restarted with each challenge, you'll | ||
need to do this for any variable you want to persist in the environment | ||
after the first challenge. | ||
|
||
## Default Cleanup Script | ||
|
||
The following is a good default cleanup script. Use this to make the | ||
shell look clean and new just like it does in tracks that don't use | ||
`tmux`. | ||
|
||
```shell | ||
#!/usr/bin/env bash | ||
|
||
# This set line ensures that all failures will cause the script to error and exit | ||
set -euxo pipefail | ||
|
||
# clear the tmux pane and scrollback to look like a fresh shell | ||
tmux clear-history -t shell | ||
tmux send-keys -t shell clear ENTER | ||
``` | ||
|
||
This is the cleanup script for this track, when you click **Check** to | ||
move on to the next challenge you can see it's results. | ||
|
||
## Testing | ||
|
||
If you use any `tmux` commands in your lifecycle scripts, you will need | ||
to make sure that the session is created if you want to run tests with | ||
`instruqt track test`. This is necessary since the test lifecycle does not | ||
run the shell commands in `config.yml`. | ||
|
||
Put the following early in your `solve-shell` script for your first | ||
challenge to make sure testing behaves. | ||
|
||
```shell | ||
### Assure the tmux session exists | ||
# | ||
# In a test scenario Instuqt does not run the user shell for the | ||
# challenge, which means the tmux session is never established. We | ||
# need to session for the solve scripts for other challenges to | ||
# succeed, so let's create it here. | ||
# | ||
|
||
if ! tmux has-session -t shell ; then | ||
tmux new-session -d -s shell su - replicant | ||
fi | ||
``` | ||
|
||
🏁 Finish | ||
========= | ||
|
||
You've now had a bit of a tour through this template. You're ready to | ||
base a lab on it. Feel free to browse through the source code to see | ||
examples of these tips in action. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
version: "3" | ||
containers: | ||
- name: shell | ||
image: gcr.io/kots-field-labs/shell | ||
shell: tmux new-session -A -s shell su - replicant | ||
virtualmachines: | ||
- name: cluster | ||
image: instruqt/k3s-v1-25-0 | ||
shell: /bin/bash | ||
machine_type: n1-standard-1 |
Oops, something went wrong.