Lifecycle scripts
This page describes the lifecycle scripts that let you control your tracks and challenges.

What is a script?

A script is a set of commands in a command or programming language that execute without compiling. Bash is a popular command language for Linux and Mac. The famous Hello World example looks like this in bash:
#!/bin/bash
echo "Hello World"
Building scripts
As a content developer, you can build scripts with the Web UI or the Instruqt CLI.

What is the lifecycle?

The lifecycle in Instruqt is a series of stages that tracks and challenges pass from setting up till cleaning up.
The track lifecycle consists of the following stages:
  • Setup
  • Cleanup
And the challenge lifecycle consists of:
  • Setup
  • Check
  • Solve
  • Cleanup

Instruqt scripts and the lifecycle

The following is a visual representation of the lifecycle stages a track and its challenges go through:
The track and challenge lifecycle stages
Content developers create lifecycle scripts that run on the sandbox hosts to:
  • Set up and clean up the sandbox environment and the challenges.
  • Check and give your learners feedback on their challenge solution.
  • Automatically solve a challenge when a learner skips a challenge.

Script features

  • All lifecycle scripts are optional.
  • Any scripting language can be used to write the scriptsβ€”for example, bash or Python, where bash is the most common choice for Instruqt.
  • Instruqt determines if a script was successful by checking the returned script exit code:
    • If the exit code is 0, Instruqt marks the script as successful.
    • If the exit code is not 0, Instruqt marks the script as unsuccessful.

Script timeouts

Every lifecycle script has a maximum duration it can take to complete. After that the script times out and will exit with an error. Scripts are not retried when it times out.
The timeouts for scripts are:
Script
Timeout
Track Setup
30 min
Track Cleanup
30 min
Challenge Setup
30 min
Challenge Check
1 min
Challenge Solve
30 min
Challenge Cleanup
30 min

Track setup script

A track setup script runs during the track setup stage. Every host within a track has its own setup script. Learners can only start playing the track if all track setup scripts have been completed successfully with an exit code 0.
Use track setup scripts to:
  • Download and install specific packages not included in the container or virtual machine image.
  • Start background services.
  • Pull down runtime configuration parameters.

Example

See this track setup script for an example of how to download and install a package.

Advanced scenarios

Hot start and track setup scripts

Instruqt starts sandboxes in advance if you have added your track to a hot start pool. In that case, any track setup script also executes in advance, leaving script parameters empty that reference a user.

How to wait for a complete bootstrap

The track setup script for a virtual machine starts to run before Instruqt has finished bootstrapping the host. Use the following snippet to wait for the bootstrap to complete. This snippet ensures that files such as /root/.bashrc will not be overwritten if you change them.
Bash
while [ ! -f /opt/instruqt/bootstrap/host-bootstrap-completed ]
do
echo "Waiting for Instruqt to finish booting the virtual machine"
sleep 1
done

Script execution order

Instruqt sorts the hosts in a track in alphanumeric order and executes the track setup scripts sequentially. If you want to run setup scripts parallel on all hosts, orchestrate the setup from the track setup script on the first host and use Secure Shell (SSH) to run scripts on other hosts.

Package updates and large downloads

If track setup speed is essential to you, avoid downloading and installing packages in the setup script. Furthermore, downloading makes the setup less reliable because downloads can fail. And your tracks could break at runtime because a newer version of a package is available.
Increase track setup speed and improve the reliability of your track by adding everything you need to the container image or virtual machine image, then use the track setup script only for runtime configuration.

Exit on failure

Instruqt marks a sandbox as failed when the track setup script fails with exit code 1. And shows the learner an error if the track plays on-demand. If the sandbox runs hot started, Instruqt discards the sandbox before a learner sees the sandbox. To avoid putting learners in unfinished sandboxes, you should exit the track setup script when a failure happens. When using bash, it is good practice to start your track setup script with the following snippet. The set command ensures that your script will stop on all errors:
Bash
#!/bin/bash
set -euxo pipefail
Preventing scripting errors
Use the online ShellCheck to find and solve bugs in your shell scripts.

Track cleanup script

A track cleanup script runs just before a sandbox environment is cleaned up. And just like with the track setup script, every host has its own cleanup script.
Use track cleanup scripts to:
  • Call external systems to trigger a clean-up.
  • Register that a user has finished with their track.

Example

See this track cleanup script for an example of removing an installed package.

Challenge setup script

A challenge setup script runs before a challenge starts.
Use challenge setup scripts to:
  • Create files that are necessary for the challenge.
  • Send analytics events.

Example

The following example creates an empty file and a pre-filled file that are available in a challenge:
Bash
#!/bin/bash
set -euxo pipefail
​
# create an empty file called challenge.txt
echo > challenge.txt
​
# create a pre-filled file called readme.md
echo " # How to create a challenge setup script " > readme.md
Follow these steps to create a challenge setup script yourself:
🌐 Web UI
πŸ’» Instruqt CLI
  1. 1.
    Open your browser and go to play.instruqt.com. ↳ Instruqt shows your content.
  2. 2.
    Click the TRACK_NAME of the track where you want to add the setup script. ↳ Instruqt shows the corresponding Track overview page.
  3. 3.
    Click Edit on the challenge where you want to add the script.
  4. 4.
    Click Scripts followed by setup. ↳ The setup file opens in the editor.
  5. 5.
    Copy the example code and paste it into the editor.
  6. 6.
    Click Save followed by Close.
  7. 7.
    Click Back.
  8. 8.
    Click Build track because you changed a lifecycle script.
  9. 9.
    Click Start track to test the challenge setup script.
  1. 1.
    Open the setup-HOSTNAME file of the challenge where you want to add a setup script in your code editor. ⇨ Replace HOSTNAME with your hostname. For example, setup-container if your host is called container.
  2. 2.
    Copy the example code and paste it into your setup-HOSTNAME file.
  3. 3.
    Save the file and deploy your track:
    instruqt track push
  4. 4.
    Start your track for testing:
    instruqt track open

Challenge check script

A challenge check script runs after a learner clicks the Check button in a challenge.
Use challenge check scripts to:
  • Check if a learner solved a challenge correctly.
  • Provide a fail message and a hint if the learner failed to solve the challenge.

Example

The following example checks if the learner created a directory called instruqt. If the learner created the directory, the script returns a success message, and Instruqt continues with the next challenge. If the learner has not created the directory, the script returns a fail message with a hint to the learner, and Instruqt stays at the current challenge.
Bash
#!/bin/bash
set -euxo pipefail
​
echo "Checking if the directory instruqt exists."
​
if [ -d /root/instruqt ]
then
echo "The directory instruqt exists"
else
fail-message "There is no directory named instruqt, did you create it?"
fi
Alternatively, the following example uses an exit code to process the challenge check. If the check fails, line 5 sends a feedback message prefixed with FAIL: to the stdout and line 6 sets the exit code to 1, which marks the script as unsuccessful:
Bash
#!/bin/bash
# check
echo "Checking the solution of the challenge"
if [ !$EVERYTHING_WENT_WELL ]; then
echo "FAIL: Your challenge failed because of [REASON]"
exit 1
fi
Follow these steps to create a challenge check script yourself:
🌐 Web UI
πŸ’» Instruqt CLI
  1. 1.
    Open your browser and go to play.instruqt.com. ↳ Instruqt shows your content.
  2. 2.
    Click the TRACK_NAME of the track where you want to add the setup script. ↳ Instruqt shows the corresponding Track overview page.
  3. 3.
    Click Edit on the challenge where you want to add the script.
  4. 4.
    Click Scripts followed by check. ↳ The setup file opens in the editor.
  5. 5.
    Copy the example code and paste it into the editor.
  6. 6.
    Click Save followed by Close.
  7. 7.
    Click Back.
  8. 8.
    Click Build track because you changed a lifecycle script.
  9. 9.
    Click Start track to test the challenge check script.
  1. 1.
    Open the check-HOSTNAME file of the challenge where you want to add a setup script in your code editor. ⇨ Replace HOSTNAME with your hostname. For example, check-container if your host is called container.
  2. 2.
    Copy the code of the first example and paste it into your check-HOSTNAME file.
  3. 3.
    Save the file and deploy your track:
    instruqt track push
  4. 4.
    Start your track for testing:
    instruqt track open

Challenge solve script

A challenge solve script solves the current challenge to allow the learner to skip ahead if you enabled skipping. Challenge solve scripts run in the following scenarios:
When running the instruqt track test command, Instruqt CLI starts the track on the Instruqt platform and executes the following challenge life cycle scripts:
  1. 1.
    setup
  2. 2.
    check ↳ Expect failure since the solve script has not been executed yet.
  3. 3.
    solve
  4. 4.
    check ↳ Expect success since the solve script has been executed.
  5. 5.
    cleanup

Example

The following example solves a challenge by creating a directory called instruqt:
Bash
#!/bin/bash
set -euxo pipefail
​
echo "Creating directory instruqt"
​
mkdir -p /root/instruqt;
Follow these steps to create a challenge setup script yourself:
🌐 Web UI
πŸ’» Instruqt CLI
  1. 1.
    Open your browser and go to play.instruqt.com. ↳ Instruqt shows your content.
  2. 2.
    Click the TRACK_NAME of the track where you want to add the setup script. ↳ Instruqt shows the corresponding Track overview page.
  3. 3.
    Click Edit on the challenge where you want to add the script.
  4. 4.
    Click Scripts followed by solve. ↳ The solve file opens in the editor.
  5. 5.
    Copy the example code and paste it into the editor.
  6. 6.
    Click Save followed by Close.
  7. 7.
    Click Back.
  8. 8.
    Click Build track because you changed a lifecycle script.
  9. 9.
    Click Start track to test the challenge setup script.
  1. 1.
    Open the solve-HOSTNAME file of the challenge where you want to add a solve script in your code editor. ⇨ Replace HOSTNAME with your hostname. For example, solve-container if your host is called container.
  2. 2.
    Copy the example code and paste it into your solve-HOSTNAME file.
  3. 3.
    Save the file and deploy your track:
    instruqt track push
  4. 4.
    Start your track for testing:
    instruqt track open

Challenge cleanup script

A challenge cleanup script runs after the learner completes a challenge before Instruqt sets up the next challenge.
Use challenge cleanup scripts to reset script artifacts for the next challenge.

Example

The following example resets an earlier file that the learner changed:
Bash
#!/bin/bash
set -euxo pipefail
​
# overwrite with an empty file
echo > challenge.txt
Follow these steps to create a challenge setup script yourself:
🌐 Web UI
πŸ’» Instruqt CLI
  1. 1.
    Open your browser and go to play.instruqt.com. ↳ Instruqt shows your content.
  2. 2.
    Click the TRACK_NAME of the track where you want to add the cleanup script. ↳ Instruqt shows the corresponding Track overview page.
  3. 3.
    Click Edit on the challenge where you want to add the script.
  4. 4.
    Click Scripts followed by cleanup. ↳ The cleanup file opens in the editor.
  5. 5.
    Copy the example code and paste it into the editor.
  6. 6.
    Click Save followed by Close.
  7. 7.
    Click Back.
  8. 8.
    Click Build track as you changed a lifecycle script.
  9. 9.
    Click Start track to test the challenge setup script.
  1. 1.
    Open the cleanup-HOSTNAME file of the challenge where you want to add a solve script in your code editor. ⇨ Replace HOSTNAME with your hostname. For example, cleanup-container if your host is called container.
  2. 2.
    Copy the example code and paste it into your cleanup-HOSTNAME file.
  3. 3.
    Save the file and deploy your track:
    instruqt track push
  4. 4.
    Start your track for testing:
    instruqt track open
You can also use lifecycle scripts to publish events to external systems. For example, you can publish an event when a user starts a track. Use the script parameters to correlate these events with data in your systems.

More examples

See the Helper scripts for some prebuilt scripts for common tasks. And see the Examples for more inspiration.

Script parameters

The Instruqt platform injects a set of environment variables, which are available as parameters in every script:
Environment Variable
Description
INSTRUQT_TRACK_ID
The ID of the track
INSTRUQT_TRACK_SLUG
The slug of the track
INSTRUQT_CHALLENGE_ID
(Optional) The ID of the challenge that the script is running on. This can be empty, in case of a track cleanup script.
INSTRUQT_PARTICIPANT_ID
The ID of the participant. This value is guaranteed to be unique for every play of a track, i.e. when a user starts the same track twice, the IDs will differ. Participant is the sandbox identifier, not a user.
INSTRUQT_TRACK_INVITE_ID
(Optional) The ID of the track invite. It is only present if the user accessed the track via an invite link.
INSTRUQT_USER_ID
(Optional) The ID of the user. This value uniquely identifies a user. Empty in a Hot Start track setup script.
INSTRUQT_USER_NAME
(Optional) The full name of the user (as they entered it when creating their account). This value is only be present if the user has given consent to share their details. For example, if a learner started a track through a track invite. Empty in a Hot Start track setup script.
INSTRUQT_USER_EMAIL
(Optional) The email address of the user. This value is only be present if the user has given consent to share their details. For example, if a learner started a track through a track invite. Empty in a Hot Start track setup script.
INSTRUQT_PRIVACY_POLICY_CONSENT
Whether the user accepted the organization's privacy policy.
On a virtual machine sandbox, start any script with #!/bin/bash -l as the first line to load the environment variables.

Example

The following challenge setup script writes the learner's name and the challenge id to the logging:
Bash
#!/bin/bash
echo $INSTRUQT_USER_NAME started challenge $INSTRUQT_CHALLENGE_ID
If you play a track that contains this script and view the track log, you will see a log entry with the learner's name and the challenge id.