# 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. ](/sandboxes/hosts/create-a-custom-vm-image.md)
{% 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.](/sandboxes/manage/hot-start.md)&#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 %}

####


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.instruqt.com/sandboxes/lifecycle-scripts/add-software-and-packages-to-a-track.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
