# Track scripts

## Overview

Track scripts are powerful ways to configure sandboxes before and after a learner uses them. \
There are two types of track scripts:

* *Setup*: Automate commands before a learner gets access to a track
* *Cleanup*: Automate commands once a learner completes a track

A typical use case for a track setup script would be to deploy pods in a Kubernetes cluster, or to clone a git repository onto a machine. Track cleanup scripts are not typically needed, but may be useful if you are managing resources outside of Instruqt sandboxes.&#x20;

Every host in a sandbox has its own setup and cleanup script. Additionally, learners can only start playing the track if all track setup scripts have been completed successfully with an exit code `0`.

{% hint style="warning" %}
The longer a track setup script runs, the longer your learners must wait. Reduce wait times by incorporating as much as you can into [custom VM images. ](https://docs.instruqt.com/sandboxes/hosts/create-a-custom-vm-image)
{% endhint %}

## Track scripts

Track setup and cleanup scripts are added using the Web UI or the Instruqt CLI.

{% tabs %}
{% tab title="🌐 Web UI" %}

1. Click the track you want to add track scripts to.
2. In the **Sandbox** menu on the right-hand side of the *Track Dashboard page*, select **Scripts**.&#x20;
3. In the web editor, determine which host you want to add track scripts to. The hosts will be listed under the *Tracks* directory in the top-left corner of the editor.
4. Add a script to the host's `setup` or `cleanup` file.
5. Click **Save**.
   {% endtab %}

{% tab title="💻 Instruqt CLI" %}

1. Track scripts are defined in the `<track-name>/track_scripts` directory and follow a `<type>-<hostname>` format. The two types of track scripts are `setup` and `cleanup`.\
   \
   For example, to add a track setup script that runs on a host named `webserver`, you must create a file named `setup-webserver` in the `track_scripts` directory. \
   \
   Here is an example structure of a track directory:<br>

   ```yaml
   my-track/
       01-example-challenge/
       track.yml
       config.yml
       track_scripts/
           setup-webserver-vm
           cleanup-database-vm
   ```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Track setup scripts are executed in advanced as part of [hot start pools.](https://docs.instruqt.com/sandboxes/manage/hot-start)&#x20;
{% endhint %}

#### Example setup script

The following is an example track setup script that installs a web server and pulls some code:

{% tabs %}
{% tab title="Bash" %}

```bash
#!/bin/bash
set -euxo pipefail

apt update
apt install nginx -y

git clone https://github.com/my-web-repo
```

{% endtab %}
{% endtabs %}

#### Example cleanup script

The following is an example track cleanup script that deletes an imaginary resource via an API call:

{% tabs %}
{% tab title="Bash" %}

```bash
#!/bin/bash
set -euxo pipefail

curl -X DELETE -s "https://example.com/api/resource/1234"
```

{% endtab %}
{% endtabs %}

## Setup scripts

There are a couple of things specific to setup scripts that are good to know.

### Wait for bootstrap

The track setup script for a host 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.

{% tabs %}
{% tab title="Bash" %}

```bash
while [ ! -f /opt/instruqt/bootstrap/host-bootstrap-completed ]
do
    echo "Waiting for Instruqt to finish booting the virtual machine"
    sleep 1
done
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Waiting for the bootstrap to complete is especially important if you plan to modify files like `/root/.bashrc` in the setup script. Generally speaking, it never hurts to add it in.&#x20;
{% endhint %}

### 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:

{% tabs %}
{% tab title="Bash" %}

```bash
#!/bin/bash 
set -euxo pipefail
```

{% endtab %}
{% endtabs %}

####
