aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Spek <p.spek@tyil.nl>2022-04-19 15:32:55 +0200
committerPatrick Spek <p.spek@tyil.nl>2022-04-19 15:32:55 +0200
commit685ccfd9e0d0d89b404129eb4ec068c923b375bc (patch)
treebadeca675a972e07315642f570da0bb6fee82c47
parent9376473a6ff9ca276aa4650a7103d631005affd9 (diff)
Add documentation
-rw-r--r--Makefile12
-rw-r--r--lib/util.bash268
-rw-r--r--lib/util/config.bash65
-rw-r--r--lib/util/pkg.bash64
-rw-r--r--lib/util/svc.bash138
-rw-r--r--share/doc/bashtard.1.scd29
-rw-r--r--share/doc/bashtard.3.scd91
-rw-r--r--share/doc/bashtard.5.scd30
-rw-r--r--share/doc/bashtard.7.scd48
-rw-r--r--share/doc/playbooks.d.7.scd32
10 files changed, 511 insertions, 266 deletions
diff --git a/Makefile b/Makefile
index 95ee0f8..4593c5a 100644
--- a/Makefile
+++ b/Makefile
@@ -25,8 +25,16 @@ lib:
mkdir -pv -- "$(DESTDIR)/lib/bashtard"
cp -rv -- lib/* "$(DESTDIR)/lib/bashtard"
+man:
+ mkdir -pv -- "$(DESTDIR)/share/man/man"{1,3,5,7}
+ scdoc < share/doc/bashtard.1.scd > "$(DESTDIR)/share/man/man1/bashtard.1"
+ scdoc < share/doc/bashtard.3.scd > "$(DESTDIR)/share/man/man3/bashtard.3"
+ scdoc < share/doc/bashtard.5.scd > "$(DESTDIR)/share/man/man5/bashtard.5"
+ scdoc < share/doc/bashtard.7.scd > "$(DESTDIR)/share/man/man7/bashtard.7"
+ scdoc < share/doc/playbooks.d.7.scd > "$(DESTDIR)/share/man/man7/playbooks.d.7"
+
share:
mkdir -pv -- "$(DESTDIR)/share/bashtard"
- cp -rv -- share/* "$(DESTDIR)/share/bashtard"
+ cp -rv -- share/{defaults,os.d} "$(DESTDIR)/share/bashtard"
-.PHONY: install uninstall bin lib share
+.PHONY: install uninstall bin lib man share
diff --git a/lib/util.bash b/lib/util.bash
index 79bac92..8a119f2 100644
--- a/lib/util.bash
+++ b/lib/util.bash
@@ -4,6 +4,10 @@
#
# SPDX-License-Identifier: AGPL-3.0-or-later
+. "$BASHTARD_LIBDIR/util/config.bash"
+. "$BASHTARD_LIBDIR/util/pkg.bash"
+. "$BASHTARD_LIBDIR/util/svc.bash"
+
# Change the working directory. In usage, this is the same as using cd,
# however, it will make additional checks to ensure everything is going fine.
chgdir() {
@@ -11,70 +15,6 @@ chgdir() {
cd -- "$1" || die "Failed to change directory to $1"
}
-# Read a particular value from a key/value configuration file. Using this
-# function introduces a dependency on awk.
-config() {
- config_for "${BASHTARD_PLATFORM[fqdn]}" "$@"
-}
-
-config_for() {
- local host=$1 ; shift
- local key=$1 ; shift
- local default=$1 ; shift
-
- local default
- local file
- local files
-
- files=(
- "$BASHTARD_ETCDIR/hosts.d/$host"
- "$BASHTARD_ETCDIR/os.d/${BASHTARD_PLATFORM[key]}"
- "$BASHTARD_ETCDIR/defaults"
- )
-
- if [[ -n "$BASHTARD_PLAYBOOK" ]]
- then
- debug "bashtard/config_for" "BASHTARD_PLAYBOOK=$BASHTARD_PLAYBOOK, adding etc entries"
- files+=(
- "$BASHTARD_ETCDIR/playbooks.d/$BASHTARD_PLAYBOOK/etc/os.d"
- "$BASHTARD_ETCDIR/playbooks.d/$BASHTARD_PLAYBOOK/etc/defaults"
- )
- fi
-
- files+=(
- "$BASHTARD_SHAREDIR/os.d/${BASHTARD_PLATFORM[key]}"
- "$BASHTARD_SHAREDIR/defaults"
- )
-
- # Check configuration files
- for file in "${files[@]}"
- do
- debug "bashtard/config_for" "Checking for '$key' in '$file'"
-
- [[ ! -f $file ]] && continue
-
- value="$(awk -F= '$1 == "'"$key"'" { print $NF }' "$file")"
-
- if [[ -n $value ]]
- then
- debug "bashtard/config_for" "Found $key=$value in $file"
-
- printf "%s" "$value"
- return
- fi
- done
-
- # Return default value
- if [[ -n $default ]]
- then
- printf "%s" "$default"
- return
- fi
-
- # Error
- alert "bashtard/config_for" "No configuration value for $key"
-}
-
# Create a datetime stamp. This is a wrapper around the date utility, ensuring
# that the date being formatted is always in UTC and respect SOURCE_DATE_EPOCH,
# if it is set.
@@ -186,206 +126,6 @@ join_args() {
printf "%s" "$*"
}
-# OS independent package management
-pkg() {
- local system="bashtard/pkg"
- local action=$1 ; shift
- local pkg
-
- pkg="$(config "pkg.$1")" ; shift
-
- if [[ -z $pkg ]]
- then
- crit "$system" "No package name for $pkg"
- return 1
- fi
-
- if [[ "$(type -t "pkg_$action")" != "function" ]]
- then
- crit "$system" "Invalid package manager action $action"
- return 1
- fi
-
- "pkg_$action" "$pkg"
-}
-
-pkg_install() {
- local system="bashtard/pkg/install"
-
- local app=$1 ; shift
-
- case "${BASHTARD_PLATFORM[key]}" in
- freebsd) set -- /usr/sbin/pkg install -y "$app" ;;
- linux-debian*) set -- apt install -y "$app" ;;
- linux-gentoo) set -- emerge --ask=n --update "$app" ;;
- *)
- crit "$system" "No package manager configured for ${BASHTARD_PLATFORM[key]}"
- return 1
- ;;
- esac
-
- notice "$system" "$*"
- # shellcheck disable=SC2068
- $@
-}
-
-pkg_uninstall() {
- local system="bashtard/pkg/uninstall"
-
- local app=$1 ; shift
-
- case "${BASHTARD_PLATFORM[key]}" in
- freebsd) set -- /usr/sbin/pkg uninstall -y "$app" ;;
- linux-debian*) set -- apt remove -y "$app" ;;
- linux-gentoo) set -- emerge --ask=n --unmerge "$app" ;;
- *)
- crit "$system" "No package manager configured for ${BASHTARD_PLATFORM[key]}"
- return 1
- ;;
- esac
-
- notice "$system" "$*"
- # shellcheck disable=SC2068
- $@
-}
-
-# OS independent service management.
-svc() {
- local system="bashtard/svc"
-
- local service
- local action
-
- action=$1 ; shift
- service="$(config "svc.$1")" ; shift
-
- if [[ -z $service ]]
- then
- crit "$system" "No service name for $service"
- return 1
- fi
-
- if [[ "$(type -t "svc_$action")" != "function" ]]
- then
- crit "$system" "Invalid service manager action $action"
- return 1
- fi
-
- "svc_$action" "$service"
-}
-
-svc_disable() {
- local system="bashtard/svc/disable"
-
- local service=$1
-
- case "${BASHTARD_PLATFORM[key]}" in
- linux-gentoo) set -- /sbin/rc-update del "$service" ;;
- linux-*) set -- systemctl disable "$service" ;;
- *)
- crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
- return 1
- esac
-
- notice "$system" "$*"
- # shellcheck disable=SC2068
- $@
-}
-
-svc_enable() {
- local system="bashtard/svc/enable"
-
- local service=$1
-
- case "${BASHTARD_PLATFORM[key]}" in
- linux-gentoo) set -- /sbin/rc-update add "$service" ;;
- linux-*) set -- systemctl enable "$service" ;;
- *)
- crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
- return 1
- esac
-
- notice "$system" "$*"
- # shellcheck disable=SC2068
- $@
-}
-
-svc_reload() {
- local system="bashtard/svc/reload"
-
- local service=$1
-
- case "${BASHTARD_PLATFORM[key]}" in
- freebsd) set -- service "$service" reload ;;
- linux-gentoo) set -- /sbin/rc-service "$service" reload ;;
- linux-*) set -- systemctl reload "$service" ;;
- *)
- crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
- return 1
- esac
-
- notice "$system" "$*"
- # shellcheck disable=SC2068
- $@
-}
-
-svc_restart() {
- local system="bashtard/svc/restart"
-
- local service=$1
-
- case "${BASHTARD_PLATFORM[key]}" in
- freebsd) set -- service "$service" restart ;;
- linux-gentoo) set -- /sbin/rc-service "$service" restart ;;
- linux-*) set -- systemctl restart "$service" ;;
- *)
- crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
- return 1
- esac
-
- notice "$system" "$*"
- # shellcheck disable=SC2068
- $@
-}
-
-svc_start() {
- local system="bashtard/svc/start"
-
- local service=$1
-
- case "${BASHTARD_PLATFORM[key]}" in
- freebsd) set -- service "$service" start ;;
- linux-gentoo) set -- /sbin/rc-service "$service" start ;;
- linux-*) set -- systemctl start "$service" ;;
- *)
- crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
- return 1
- esac
-
- notice "$system" "$*"
- # shellcheck disable=SC2068
- $@
-}
-
-svc_stop() {
- local system="bashtard/svc/stop"
-
- local service=$1
-
- case "${BASHTARD_PLATFORM[key]}" in
- freebsd) set -- service "$service" stop ;;
- linux-gentoo) set -- /sbin/rc-service "$service" stop ;;
- linux-*) set -- systemctl stop "$service" ;;
- *)
- crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
- return 1
- esac
-
- notice "$system" "$*"
- # shellcheck disable=SC2068
- $@
-}
-
file_template()
{
local file="$BASHTARD_ETCDIR/playbooks.d/$BASHTARD_PLAYBOOK/share/$1" ; shift
diff --git a/lib/util/config.bash b/lib/util/config.bash
new file mode 100644
index 0000000..a3b1727
--- /dev/null
+++ b/lib/util/config.bash
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+
+# Read a particular value from a key/value configuration file. Using this
+# function introduces a dependency on awk.
+config() {
+ config_for "${BASHTARD_PLATFORM[fqdn]}" "$@"
+}
+
+config_for() {
+ local host=$1 ; shift
+ local key=$1 ; shift
+ local default=$1 ; shift
+
+ local default
+ local file
+ local files
+
+ files=(
+ "$BASHTARD_ETCDIR/hosts.d/$host"
+ "$BASHTARD_ETCDIR/os.d/${BASHTARD_PLATFORM[key]}"
+ "$BASHTARD_ETCDIR/defaults"
+ )
+
+ if [[ -n "$BASHTARD_PLAYBOOK" ]]
+ then
+ debug "bashtard/config_for" "BASHTARD_PLAYBOOK=$BASHTARD_PLAYBOOK, adding etc entries"
+ files+=(
+ "$BASHTARD_ETCDIR/playbooks.d/$BASHTARD_PLAYBOOK/etc/os.d"
+ "$BASHTARD_ETCDIR/playbooks.d/$BASHTARD_PLAYBOOK/etc/defaults"
+ )
+ fi
+
+ files+=(
+ "$BASHTARD_SHAREDIR/os.d/${BASHTARD_PLATFORM[key]}"
+ "$BASHTARD_SHAREDIR/defaults"
+ )
+
+ # Check configuration files
+ for file in "${files[@]}"
+ do
+ debug "bashtard/config_for" "Checking for '$key' in '$file'"
+
+ [[ ! -f $file ]] && continue
+
+ value="$(awk -F= '$1 == "'"$key"'" { print $NF }' "$file")"
+
+ if [[ -n $value ]]
+ then
+ debug "bashtard/config_for" "Found $key=$value in $file"
+
+ printf "%s" "$value"
+ return
+ fi
+ done
+
+ # Return default value
+ if [[ -n $default ]]
+ then
+ printf "%s" "$default"
+ return
+ fi
+
+ # Error
+ alert "bashtard/config_for" "No configuration value for $key"
+}
diff --git a/lib/util/pkg.bash b/lib/util/pkg.bash
new file mode 100644
index 0000000..618ce6a
--- /dev/null
+++ b/lib/util/pkg.bash
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+
+# OS independent package management
+pkg() {
+ local system="bashtard/pkg"
+ local action=$1 ; shift
+ local pkg
+
+ pkg="$(config "pkg.$1")" ; shift
+
+ if [[ -z $pkg ]]
+ then
+ crit "$system" "No package name for $pkg"
+ return 1
+ fi
+
+ if [[ "$(type -t "pkg_$action")" != "function" ]]
+ then
+ crit "$system" "Invalid package manager action $action"
+ return 1
+ fi
+
+ "pkg_$action" "$pkg"
+}
+
+pkg_install() {
+ local system="bashtard/pkg/install"
+
+ local app=$1 ; shift
+
+ case "${BASHTARD_PLATFORM[key]}" in
+ freebsd) set -- /usr/sbin/pkg install -y "$app" ;;
+ linux-debian*) set -- apt install -y "$app" ;;
+ linux-gentoo) set -- emerge --ask=n --update "$app" ;;
+ *)
+ crit "$system" "No package manager configured for ${BASHTARD_PLATFORM[key]}"
+ return 1
+ ;;
+ esac
+
+ notice "$system" "$*"
+ # shellcheck disable=SC2068
+ $@
+}
+
+pkg_uninstall() {
+ local system="bashtard/pkg/uninstall"
+
+ local app=$1 ; shift
+
+ case "${BASHTARD_PLATFORM[key]}" in
+ freebsd) set -- /usr/sbin/pkg uninstall -y "$app" ;;
+ linux-debian*) set -- apt remove -y "$app" ;;
+ linux-gentoo) set -- emerge --ask=n --unmerge "$app" ;;
+ *)
+ crit "$system" "No package manager configured for ${BASHTARD_PLATFORM[key]}"
+ return 1
+ ;;
+ esac
+
+ notice "$system" "$*"
+ # shellcheck disable=SC2068
+ $@
+}
diff --git a/lib/util/svc.bash b/lib/util/svc.bash
new file mode 100644
index 0000000..403615f
--- /dev/null
+++ b/lib/util/svc.bash
@@ -0,0 +1,138 @@
+#!/usr/bin/env bash
+
+# OS independent service management.
+svc() {
+ local system="bashtard/svc"
+
+ local service
+ local action
+
+ action=$1 ; shift
+ service="$(config "svc.$1")" ; shift
+
+ if [[ -z $service ]]
+ then
+ crit "$system" "No service name for $service"
+ return 1
+ fi
+
+ if [[ "$(type -t "svc_$action")" != "function" ]]
+ then
+ crit "$system" "Invalid service manager action $action"
+ return 1
+ fi
+
+ "svc_$action" "$service"
+}
+
+svc_disable() {
+ local system="bashtard/svc/disable"
+
+ local service=$1
+
+ case "${BASHTARD_PLATFORM[key]}" in
+ linux-gentoo) set -- /sbin/rc-update del "$service" ;;
+ linux-*) set -- systemctl disable "$service" ;;
+ *)
+ crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
+ return 1
+ esac
+
+ notice "$system" "$*"
+ # shellcheck disable=SC2068
+ $@
+}
+
+svc_enable() {
+ local system="bashtard/svc/enable"
+
+ local service=$1
+
+ case "${BASHTARD_PLATFORM[key]}" in
+ linux-gentoo) set -- /sbin/rc-update add "$service" ;;
+ linux-*) set -- systemctl enable "$service" ;;
+ *)
+ crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
+ return 1
+ esac
+
+ notice "$system" "$*"
+ # shellcheck disable=SC2068
+ $@
+}
+
+svc_reload() {
+ local system="bashtard/svc/reload"
+
+ local service=$1
+
+ case "${BASHTARD_PLATFORM[key]}" in
+ freebsd) set -- service "$service" reload ;;
+ linux-gentoo) set -- /sbin/rc-service "$service" reload ;;
+ linux-*) set -- systemctl reload "$service" ;;
+ *)
+ crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
+ return 1
+ esac
+
+ notice "$system" "$*"
+ # shellcheck disable=SC2068
+ $@
+}
+
+svc_restart() {
+ local system="bashtard/svc/restart"
+
+ local service=$1
+
+ case "${BASHTARD_PLATFORM[key]}" in
+ freebsd) set -- service "$service" restart ;;
+ linux-gentoo) set -- /sbin/rc-service "$service" restart ;;
+ linux-*) set -- systemctl restart "$service" ;;
+ *)
+ crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
+ return 1
+ esac
+
+ notice "$system" "$*"
+ # shellcheck disable=SC2068
+ $@
+}
+
+svc_start() {
+ local system="bashtard/svc/start"
+
+ local service=$1
+
+ case "${BASHTARD_PLATFORM[key]}" in
+ freebsd) set -- service "$service" start ;;
+ linux-gentoo) set -- /sbin/rc-service "$service" start ;;
+ linux-*) set -- systemctl start "$service" ;;
+ *)
+ crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
+ return 1
+ esac
+
+ notice "$system" "$*"
+ # shellcheck disable=SC2068
+ $@
+}
+
+svc_stop() {
+ local system="bashtard/svc/stop"
+
+ local service=$1
+
+ case "${BASHTARD_PLATFORM[key]}" in
+ freebsd) set -- service "$service" stop ;;
+ linux-gentoo) set -- /sbin/rc-service "$service" stop ;;
+ linux-*) set -- systemctl stop "$service" ;;
+ *)
+ crit "$system" "No service manager configured for ${BASHTARD_PLATFORM[key]}"
+ return 1
+ esac
+
+ notice "$system" "$*"
+ # shellcheck disable=SC2068
+ $@
+}
diff --git a/share/doc/bashtard.1.scd b/share/doc/bashtard.1.scd
new file mode 100644
index 0000000..c176c57
--- /dev/null
+++ b/share/doc/bashtard.1.scd
@@ -0,0 +1,29 @@
+bashtard(1)
+
+# NAME
+
+bashtard - A Bash-based configuration management utility
+
+# SYNOPSIS
+
+*bashtard* -h++
+*bashtard* add <_playbook_>++
+*bashtard* bootstrap [_repository_]++
+*bashtard* del <_playbook_>++
+*bashtard* ssh <_command_>++
+*bashtard* sync [_playbook_]++
+*bashtard* sysinfo
+
+# DESCRIPTION
+
+*bashtard* is a relatively simple Bash-based utility, providing just enough
+abstractions over certain OS-specific tools to allow you to write generic
+configuration and maintainance scripts, known as *playbooks*.
+
+# SEE ALSO
+
+- _bashtard(3)_ -- Functions and variables exposed by *bashtard* for use in
+ playbooks
+- _bashtard(5)_ -- Configuration files and formats used by *bashtard*
+- _bashtard(7)_ -- Filesystem layout for /etc/bashtard
+- _playbooks.d(7)_ -- Filesystem layout for /etc/bashtard/playbooks.d
diff --git a/share/doc/bashtard.3.scd b/share/doc/bashtard.3.scd
new file mode 100644
index 0000000..2ae4bdc
--- /dev/null
+++ b/share/doc/bashtard.3.scd
@@ -0,0 +1,91 @@
+bashtard(3)
+
+# INTRODUCTION
+
+When writing a *playbook*, you will want to know of the variables and functions
+exposed by *bashtard*, so that you can actually write OS-agnostic installation
+and maintainance scripts.
+
+# VARIABLES
+
+These are the variables which are supported by *bashtard* for use in
+*playbooks*. There are more *$BASHTARD_* variables, but these are intended for
+internal use only, and should thus *NOT* be relied on in *playbooks*.
+
+## BASHTARD_BIN
+
+The absolute path to the *bashtard* binary.
+
+## BASHTARD_PLATFORM
+
+The *$BASHTARD_PLATFORM* variable contains all sorts of information about the
+platform it is currently running on. It is an array with the following keys:
+
+- arch -- The name of the architecture
+- distro -- The name of the GNU+Linux distribution, if any
+- fqdn -- The fully-qualified domain name of the machine
+- key -- A "key" to uniquely identify the OS
+- os -- The name of the OS
+- term -- The name of the current-running terminal
+- version -- The release version of the OS, if any
+
+These can be used to handle edge-cases when trying to configure things, though
+with abstractions like _pkg_ and _svc_, you shouldn't need these directly. The
+*key* of the *$BASHTARD_PLATFORM* array is used to find the right configuration
+file in *os.d* for configuration value resolution. Refer to _bashtard(5)_ for
+more information on this.
+
+## BASHTARD_PLAYBOOK
+
+The name of the currently running playbook.
+
+# FUNCTIONS
+
+## config $key
+
+The *config()* function lets you retrieve a particular config value based on the
+given _key_. Refer to _bashtard(5)_ for more information about configuration
+value resolution.
+
+## file_template $template [$var ...]
+
+The *file_template()* function lets you perform simple templating on a file.
+There is no logic, only very simple substitution through the power of *sed*. You
+can specify any number of _var_ arguments as key=value pairs, which will be
+substituted in the template file. In the template, you can specify these as
+_${key}_. The templates will be looked for in the *share* directory inside the
+playbook directory.
+
+## pkg $action $pkg
+
+The *pkg()* function abstracts away the running system's package manager,
+allowing you to write more OS-agnostic playbooks. The _action_ can be either
+*install* or *uninstall*. The actual package name which will be installed will
+be looked up through *config()*, in the form of _pkg.$pkg_.
+
+For instance, if you call *pkg install nginx*, the *pkg()* function will try to
+resolve the *pkg.nginx*, and install whichever value it came up with. These are
+generally defined in the *os.d* of a *playbook*, to handle situations where
+certain systems name their packages differently.
+
+## svc $action $svc
+
+The *svc()* function abstracts away the running system's service manager,
+allowing you to write more OS-agnostic playbooks. The _action_ can be one of the
+following:
+
+- *disable*
+- *enable*
+- *start*
+- *stop*
+- *reload*
+- *restart*
+
+The actual service name which will be acted upon will be looked up through
+*config()*, in the form of _svc.$svc_, much like with the *pkg()* function.
+
+## tmpfile
+
+The *tmpfile()* function lets you create temporary files as needed. It does not
+take an argument, and returns you a path for a temporary file to which you can
+write. Cleanup will be done automatically after *bashtard* exits.
diff --git a/share/doc/bashtard.5.scd b/share/doc/bashtard.5.scd
new file mode 100644
index 0000000..c7791cf
--- /dev/null
+++ b/share/doc/bashtard.5.scd
@@ -0,0 +1,30 @@
+bashtard(5)
+
+# INTRODUCTION
+
+When it comes to configuration, *bashtard* checks various locations for files
+defining key-value pairs, mostly for use in *playbooks*. The files use a very
+simple _key_=_value_ construction. The _key_ cannot contain an equals sign (=),
+but the _value_ can. Quotes around the _value_ are not needed. If you add these,
+they will be taken literally. If a _key_ is found in multiple configuration
+files, the first hit will be used and subsequent files will not be tried.
+
+# PATHS
+
+The following paths are tried, in order, from top to bottom, to find a _key_:
+
+- $BASHTARD_ETCDIR/hosts.d/$host
+- $BASHTARD_ETCDIR/os.d/${BASHTARD_PLATFORM[key]}
+- $BASHTARD_ETCDIR/defaults
+- $BASHTARD_ETCDIR/playbooks.d/$BASHTARD_PLAYBOOK/etc/os.d
+- $BASHTARD_ETCDIR/playbooks.d/$BASHTARD_PLAYBOOK/etc/defaults
+- $BASHTARD_SHAREDIR/os.d/${BASHTARD_PLATFORM[key]}
+- $BASHTARD_SHAREDIR/defaults
+
+The *$BASHTARD_* variables are set by *bashtard* itself. More information about
+these variables can be found in _bashtard(3)_.
+
+# SEE ALSO
+
+- _bashtard(3)_ -- Functions and variables exposed by *bashtard* for use in
+ playbooks
diff --git a/share/doc/bashtard.7.scd b/share/doc/bashtard.7.scd
new file mode 100644
index 0000000..6e989c4
--- /dev/null
+++ b/share/doc/bashtard.7.scd
@@ -0,0 +1,48 @@
+bashtard(7) "/etc/bashtard"
+
+# HIERARCHY
+
+# defaults
+
+The defaults file is a _bashtard(5)_ key-value file. It specifies the values of
+variables in case there are no host or os specific values.
+
+# hosts.d
+
+The *hosts.d* directory contains one file for each specific host you're managing
+with *bashtard*, in the _bashtard(5)_ key-value format. The variables defined in
+this file take precedence over those defined in *os.d*.
+
+# os.d
+
+The *os.d* directory contains any number of files, named after the _key_ value
+reported by *bashtard sysinfo*. This allows you to set variables on a
+os-by-os basis, for instance for package names which differ between between
+certain GNU+Linux distributions.
+
+# playbooks.d
+
+The *playbooks.d* directory contains a single plain-text file, *remotes*,
+describing all the remote playbooks tracked by *bashtard*. The layout of
+playbooks themselves can be found in _playbooks.d(7)_.
+
+## remotes
+
+The *remotes* file is a space-seperated file, specifying a _name_, _url_, and
+_branch_ per line, to use for keeping remote playbooks synchronized.
+
+```
+webserver https://git.tyil.nl/bashtard-webserver.git master
+```
+
+# registry.d
+
+The *registry.d* contains one file for each specific host you're managing with
+*bashtard*. It keeps track of which playbooks are added to each host, to use
+when the *sync* subcommand is invoked. Entries get added to this registry
+automatically when using the *add* subcommand, and removed when using the *del*
+subcommand.
+
+# SEE ALSO
+
+- _bashtard(5)_ -- Configuration files and formats used by Bashtard
diff --git a/share/doc/playbooks.d.7.scd b/share/doc/playbooks.d.7.scd
new file mode 100644
index 0000000..1d2af2e
--- /dev/null
+++ b/share/doc/playbooks.d.7.scd
@@ -0,0 +1,32 @@
+playbooks.d(7) "/etc/bashtard/playbooks.d"
+
+# INTRODUCTION
+
+*bashtard* playbooks are, in essence, no more than directories with a small
+number of required files. Even remote playbooks just get cloned into regular
+directories inside _playbooks.d_. The files you must include in any playbook
+are:
+
+- description.txt
+- playbook.bash
+
+The filename are case sensitive, and the extensions are required.
+
+# HIERARCHY
+
+# description.txt
+
+This is a small text file which contains a small description of the playbook,
+usually only a single sentence. This description is shown in the usage output of
+*bashtard*.
+
+# playbook.bash
+
+The _playbook.bash_ file is a regular Bash script. It must contain 3 specific
+functions, which are called by *bashtard* when the appropriate subcommand is
+invoked. These functions are _playbook_add()_, _playbook_sync()_, and
+_playbook_del()_. How you define these functions is up to you.
+
+# SEE ALSO
+
+- _bashtard(3)_ -- Variables and functions exposed by Bashtard