How-Tos
General
Modify the tutorial for documentation or runtime
Although antithetical to the core promise of this project, sometimes it is unavoidable to run commands differently from how they are rendered in documentation. Examples are commands that read passwords (and avoid reading data from stdin):
parts:
- commands:
- command: "{% if doc %}passwd{% else %}sudo sed 's/..../' /etc/shadow{% endif %}"
This will render as:
user@host:~$ passwd
… but in reality will run the sudo command to update the password file directly.
Running commands
Test for installed tools
You can specify a list of tools that is required for running the tutorial. structured-tutorials will then
test if a certain tool is installed before starting the tutorial and present the user with a nice error
message:
configuration:
run:
# Don't even start if git is not installed
required_executables:
- git
# Require db clients only if alternative is selected
alternatives:
mariadb:
required_executables:
- mariadb
postgres:
required_executables:
- psql
parts:
- commands:
- command: git checkout
# ...
user@host:~$ git checkout
Cleanup after running a tutorial
To cleanup after after running a tutorial, specify a set of cleanup commands:
parts:
- commands:
- command: mkdir -p /tmp/new-directory
run:
cleanup:
- command: rm -r /tmp/new-directory
Cleanup commands are not rendered in documentation, so this will simply render as:
user@host:~$ mkdir -p /tmp/new-directory
If multiple cleanup commands are specified, they will run in-order. In case of an error, only cleanup commands for commands that where actually run will be executed. Consider this example:
parts:
- commands:
- command: cmd1
run:
cleanup:
- command: clean1
- command: clean2
- command: cmd2
run:
cleanup:
- command: clean3
Assuming cmd1 and cmd2 run successfully (or cmd2 exits with a non-zero status code), this will
run, in order, clean3, clean1 and clean2. Should cmd1 return a non-zero status code, only
clean1 and clean2 will be run.
Skip a part at runtime
To skip an entire part at runtime, but still show it in documentation, simply set run: false:
parts:
- commands:
- command: ls /tmp
doc:
output: ...
run: false
# We could also skip part in documentation instead:
#doc: false
- commands:
- command: ls /etc
doc:
output: ...
# Or we could skip just a command, not the entire part, at runtime:
- command: ls /tmp
run: false
doc:
output: ...
When running the tutorial, only the first part will run:
user@host:~$ structured-tutorial docs/tutorials/skip-part-run/tutorial.yam
+ ls /etc
...
But when generating documentation, both parts will show, for example, this is part one:
user@host:~$ ls /tmp
...
… and this is part two:
user@host:~$ ls /etc
...
user@host:~$ ls /tmp
...
Documenting commands
Show output
To show an output when rendering commands, specify the output key:
parts:
- commands:
- command: echo "example output"
doc:
output: "example output"
This will render as:
user@host:~$ echo "example output"
example output
Template context
Both command and output are rendered as template with the current context. The initial context is specified in the global context, and each command can update the context before and after being shown:
configuration:
doc:
context:
user_id: 1000
path: test.txt
parts:
- commands:
# For some reason, compute twice your own user id
- command: echo "{{ user_id }} * 2" | bc -l > test.txt
doc:
update_context:
contents: 2000
- command: cat {{ path }}
doc:
output: "{{ contents }}"
This will render as:
user@host:~$ echo "1000 * 2" | bc -l > test.txt
user@host:~$ cat test.txt
2000
Update the command prompt
To configure the initial command prompt, set below context variables in the initial context. You can update those variables at any time. The following variables influence the prompt:
- prompt
Default:
"{{ user }}@{{ host }}:{{ cwd }}{% if user == 'root' %}#{% else %}${% endif %} "The template used to render the prompt, which includes the values below.
- user
Default:
"user"The username rendered in the prompt.
- host
Default:
"host"The hostname rendered in the prompt.
- cwd
Default:
"~"The current working directory rendered in the prompt.
configuration:
doc:
context:
user: example-user
host: example-host
cwd: /tmp
parts:
- commands:
- command: sudo su
doc:
update_context:
user: root
- command: cd /etc
doc:
update_context:
cwd: /etc
- command: pwd
doc:
output: /etc
This will render as:
example-user@example-host:/tmp$ sudo su
root@example-host:/tmp# cd /etc
root@example-host:/etc# pwd
/etc
Skip a part in documentation
To skip an entire part for documentation purposes, but still use it at runtime, you can use the skip
configuration:
parts:
- commands:
- command: ls /tmp
doc:
output: ...
# We could also skip part at runtime instead:
#run: false
doc: false
- commands:
- command: ls /etc
doc:
output: ...
When running the tutorial, only the first part will run:
user@host:~$ structured-tutorial docs/tutorials/skip-part-run/tutorial.yaml
+ ls /tmp
...
+ ls /etc
...
But when generating documentation, only the first part can be used. Calling structured-tutorial-part a
second time will lead to an error (as there are no parts left).
user@host:~$ ls /etc
...