From 88bf5771ead1ba6e70efafb462b7ae4e7e4c02d5 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 27 Apr 2021 18:04:56 +0000 Subject: [PATCH 01/10] vagrant: Use source instead of . for better grepability. Signed-off-by: Manuel Mendez --- deploy/vagrant/scripts/tinkerbell.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/vagrant/scripts/tinkerbell.sh b/deploy/vagrant/scripts/tinkerbell.sh index 290fcfb..d2d7a6d 100644 --- a/deploy/vagrant/scripts/tinkerbell.sh +++ b/deploy/vagrant/scripts/tinkerbell.sh @@ -39,7 +39,7 @@ main() ( fi # shellcheck disable=SC1091 - . ./.env + source ./.env make_certs_writable From b8d94f52785471da9faa58b6986ac00c3149f3f9 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 27 Apr 2021 15:01:59 +0000 Subject: [PATCH 02/10] setup.sh: Quote full args instead of just bash variables More in line with the rest of scripts and is easier to mentally parse. Signed-off-by: Manuel Mendez --- setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.sh b/setup.sh index 5680601..2164490 100755 --- a/setup.sh +++ b/setup.sh @@ -347,8 +347,8 @@ generate_certificates() ( local certs_dir="/etc/docker/certs.d/$TINKERBELL_HOST_IP" # copy public key to NGINX for workers - if ! cmp --quiet "$STATEDIR"/certs/ca.pem "$STATEDIR/webroot/workflow/ca.pem"; then - cp "$STATEDIR"/certs/ca.pem "$STATEDIR/webroot/workflow/ca.pem" + if ! cmp --quiet "$STATEDIR/certs/ca.pem" "$STATEDIR/webroot/workflow/ca.pem"; then + cp "$STATEDIR/certs/ca.pem" "$STATEDIR/webroot/workflow/ca.pem" fi # update host to trust registry certificate From 0fff3e6d7f26897e048dc19ddae21b1fab41554d Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 27 Apr 2021 17:39:50 +0000 Subject: [PATCH 03/10] sh: Make use of bashisms in bash scripts Both [[ ]] and (( )) bashisms are better than the alternative in POSIX sh, since they are builtin and don't suffer from quoting or number-of-args issues. Signed-off-by: Manuel Mendez --- deploy/vagrant/scripts/tinkerbell.sh | 2 +- generate-env.sh | 4 +-- setup.sh | 38 ++++++++++++++-------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/deploy/vagrant/scripts/tinkerbell.sh b/deploy/vagrant/scripts/tinkerbell.sh index d2d7a6d..66b005a 100644 --- a/deploy/vagrant/scripts/tinkerbell.sh +++ b/deploy/vagrant/scripts/tinkerbell.sh @@ -34,7 +34,7 @@ setup_nat() ( main() ( export DEBIAN_FRONTEND=noninteractive - if [ ! -f ./.env ]; then + if ! [[ -f ./.env ]]; then ./generate-env.sh eth1 >.env fi diff --git a/generate-env.sh b/generate-env.sh index e6fb304..84f6855 100755 --- a/generate-env.sh +++ b/generate-env.sh @@ -14,7 +14,7 @@ ERR="${RED:-}ERROR:${RESET:-}" source ./current_versions.sh err() ( - if [ -z "${1:-}" ]; then + if [[ -z ${1:-} ]]; then cat >&2 else echo "$ERR " "$@" >&2 @@ -94,7 +94,7 @@ EOF ) main() ( - if [ -z "${1:-}" ]; then + if [[ -z ${1:-} ]]; then err "Usage: $0 network-interface-name > .env" exit 1 fi diff --git a/setup.sh b/setup.sh index 2164490..bedf3ca 100755 --- a/setup.sh +++ b/setup.sh @@ -38,7 +38,7 @@ NEXT="${GREEN:-}NEXT:${RESET:-}" get_distribution() ( local lsb_dist="" # Every system that we officially support has /etc/os-release - if [ -r /etc/os-release ]; then + if [[ -r /etc/os-release ]]; then # shellcheck disable=SC1091 lsb_dist="$(. /etc/os-release && echo "$ID")" fi @@ -50,7 +50,7 @@ get_distribution() ( get_distro_version() ( local lsb_version="0" # Every system that we officially support has /etc/os-release - if [ -r /etc/os-release ]; then + if [[ -r /etc/os-release ]]; then # shellcheck disable=SC1091 lsb_version="$(. /etc/os-release && echo "$VERSION_ID")" fi @@ -112,10 +112,10 @@ setup_networking() ( fi NAT_INTERFACE="" - if [ -r .nat_interface ]; then + if [[ -r .nat_interface ]]; then NAT_INTERFACE=$(cat .nat_interface) fi - if [ -n "$NAT_INTERFACE" ] && ip addr show "$NAT_INTERFACE" &>/dev/null; then + if [[ -n $NAT_INTERFACE ]] && ip addr show "$NAT_INTERFACE" &>/dev/null; then # TODO(nshalman) the terraform code would just run these commands as-is once # but it would be nice to make these more persistent based on OS iptables -A FORWARD -i "$TINKERBELL_NETWORK_INTERFACE" -o "$NAT_INTERFACE" -j ACCEPT @@ -135,10 +135,10 @@ setup_networking_manually() ( setup_network_forwarding() ( # enable IP forwarding for docker - if [ "$(sysctl -n net.ipv4.ip_forward)" != "1" ]; then - if [ -d /etc/sysctl.d ]; then + if (($(sysctl -n net.ipv4.ip_forward) != 1)); then + if [[ -d /etc/sysctl.d ]]; then echo "net.ipv4.ip_forward=1" >/etc/sysctl.d/99-tinkerbell.conf - elif [ -f /etc/sysctl.conf ]; then + elif [[ -f /etc/sysctl.conf ]]; then echo "net.ipv4.ip_forward=1" >>/etc/sysctl.conf fi @@ -171,7 +171,7 @@ setup_networking_netplan() ( ) setup_networking_ubuntu_legacy() ( - if [ ! -f /etc/network/interfaces ]; then + if ! [[ -f /etc/network/interfaces ]]; then echo "$ERR file /etc/network/interfaces not found" exit 1 fi @@ -224,7 +224,7 @@ EOF local cfgfile="/etc/sysconfig/network-scripts/ifcfg-$TINKERBELL_NETWORK_INTERFACE" - if [ -f "$cfgfile" ]; then + if [[ -f $cfgfile ]]; then echo "$ERR network config already exists: $cfgfile" echo "$BLANK Please update it to match this configuration:" echo "$content" @@ -245,12 +245,12 @@ setup_osie() ( local osie_current=$STATEDIR/webroot/misc/osie/current local tink_workflow=$STATEDIR/webroot/workflow/ - if [ ! -d "$osie_current" ] || [ ! -d "$tink_workflow" ]; then + if [[ ! -d $osie_current ]] || [[ ! -d $tink_workflow ]]; then mkdir -p "$osie_current" mkdir -p "$tink_workflow" pushd "$SCRATCH" - if [ -z "${TB_OSIE_TAR:-}" ]; then + if [[ -z ${TB_OSIE_TAR:-} ]]; then curl "${OSIE_DOWNLOAD_LINK}" -o ./osie.tar.gz tar -zxf osie.tar.gz else @@ -305,7 +305,7 @@ check_container_status() ( --filter "event=health_status" \ --format '{{.Status}}') - if [ "$status" != "health_status: healthy" ]; then + if [[ $status != "health_status: healthy" ]]; then echo "$ERR $container_name is not healthy. status: $status" exit 1 fi @@ -314,7 +314,7 @@ check_container_status() ( generate_certificates() ( mkdir -p "$STATEDIR/certs" - if [ ! -f "$STATEDIR/certs/ca.json" ]; then + if ! [[ -f "$STATEDIR/certs/ca.json" ]]; then jq \ '. | .names[0].L = $facility @@ -325,7 +325,7 @@ generate_certificates() ( >"$STATEDIR/certs/ca.json" fi - if [ ! -f "$STATEDIR/certs/server-csr.json" ]; then + if ! [[ -f "$STATEDIR/certs/server-csr.json" ]]; then jq \ '. | .hosts += [ $ip, "tinkerbell.\($facility).packet.net" ] @@ -353,7 +353,7 @@ generate_certificates() ( # update host to trust registry certificate if ! cmp --quiet "$STATEDIR/certs/ca.pem" "$certs_dir/tinkerbell.crt"; then - if [ ! -d "$certs_dir/tinkerbell.crt" ]; then + if ! [[ -d "$certs_dir/" ]]; then # The user will be told to create the directory # in the next block, if copying the certs there # fails. @@ -363,7 +363,7 @@ generate_certificates() ( echo "$ERR please copy $STATEDIR/certs/ca.pem to $certs_dir/tinkerbell.crt" echo "$BLANK and run $0 again:" - if [ ! -d "$certs_dir" ]; then + if ! [[ -d $certs_dir ]]; then echo "sudo mkdir -p '$certs_dir'" fi echo "sudo cp '$STATEDIR/certs/ca.pem' '$certs_dir/tinkerbell.crt'" @@ -406,7 +406,7 @@ bootstrap_docker_registry() ( setup_docker_registry() ( local registry_images="$STATEDIR/registry" - if [ ! -d "$registry_images" ]; then + if ! [[ -d $registry_images ]]; then mkdir -p "$registry_images" fi start_registry @@ -469,7 +469,7 @@ check_prerequisites() ( ;; esac - if [ $failed -eq 1 ]; then + if ((failed == 1)); then echo "$ERR Prerequisites not met. Please install the missing commands and re-run $0." exit 1 fi @@ -489,7 +489,7 @@ do_setup() ( echo "$INFO starting tinkerbell stack setup" check_prerequisites "$lsb_dist" "$lsb_version" - if [ ! -f "$ENV_FILE" ]; then + if ! [[ -f $ENV_FILE ]]; then echo "$ERR Run './generate-env.sh network-interface > \"$ENV_FILE\"' before continuing." exit 1 fi From 8e5430bfd14dcb9e247d20bce668ed678be1a846 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 27 Apr 2021 17:45:16 +0000 Subject: [PATCH 04/10] generate-env: Use <<-EOF to indent the heredoc Indentation is helpful to know a function's scope. Not indenting the heredoc makes scanning harder. Signed-off-by: Manuel Mendez --- generate-env.sh | 63 +++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/generate-env.sh b/generate-env.sh index 84f6855..8e77018 100755 --- a/generate-env.sh +++ b/generate-env.sh @@ -53,44 +53,45 @@ generate_env() ( tink_password=$(generate_password) local registry_password registry_password=$(generate_password) - cat < Date: Tue, 27 Apr 2021 17:57:42 +0000 Subject: [PATCH 05/10] box: make lists be multiline and with same line ending Better for adding/removing things this way. Signed-off-by: Manuel Mendez --- deploy/vagrant/basebox/ubuntu1804/provision.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/deploy/vagrant/basebox/ubuntu1804/provision.sh b/deploy/vagrant/basebox/ubuntu1804/provision.sh index f74d423..6c84e60 100644 --- a/deploy/vagrant/basebox/ubuntu1804/provision.sh +++ b/deploy/vagrant/basebox/ubuntu1804/provision.sh @@ -9,7 +9,8 @@ setup_docker() ( ca-certificates \ curl \ gnupg-agent \ - software-properties-common + software-properties-common \ + ; curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - @@ -22,7 +23,11 @@ setup_docker() ( sudo add-apt-repository "$repo" sudo apt-get update - sudo apt-get install -y docker-ce docker-ce-cli containerd.io + sudo apt-get install -y \ + containerd.io \ + docker-ce \ + docker-ce-cli \ + ; ) setup_docker_compose() ( From 51777df36c459d6a90681cb000b95286d2b5acc9 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 27 Apr 2021 18:10:31 +0000 Subject: [PATCH 06/10] setup: Add xtrace and pipefail to set options pipefail for more safety and xtrace for better debuggability. The missing xtrace here is likely what led to the docker-compose issue going unfixed for so long as the last bit of output was from the gencerts container and did not make any sense (because it wasn't the issue :D ). Signed-off-by: Manuel Mendez --- setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.sh b/setup.sh index bedf3ca..50e0621 100755 --- a/setup.sh +++ b/setup.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # stops the execution if a command or pipeline has an error -set -eu +set -euxo pipefail # Tinkerbell stack Linux setup script # From 4a59c96463e66175909d9190f8203efa92818c00 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 27 Apr 2021 18:10:40 +0000 Subject: [PATCH 07/10] vagrant: Ensure the whats_next message is printed at the end The tinkerbell.sh script ends up doing some other work after calling setup.sh and has set -x enabled so the whats_next message is likely to be missed. So now save it for later reading as the last thing done. Signed-off-by: Manuel Mendez --- deploy/vagrant/scripts/tinkerbell.sh | 3 +++ setup.sh | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/deploy/vagrant/scripts/tinkerbell.sh b/deploy/vagrant/scripts/tinkerbell.sh index 66b005a..915f27f 100644 --- a/deploy/vagrant/scripts/tinkerbell.sh +++ b/deploy/vagrant/scripts/tinkerbell.sh @@ -51,6 +51,9 @@ main() ( secure_certs configure_vagrant_user + + set +x # don't want the stderr output from xtrace messing with the post-setup-message + [[ -f /tmp/post-setup-message ]] && cat /tmp/post-setup-message ) main diff --git a/setup.sh b/setup.sh index 50e0621..59da9aa 100755 --- a/setup.sh +++ b/setup.sh @@ -503,7 +503,7 @@ do_setup() ( setup_docker_registry echo "$INFO tinkerbell stack setup completed successfully on $lsb_dist server" - whats_next + whats_next | tee /tmp/post-setup-message ) # wrapped up in a function so that we have some protection against only getting From 549e540671e685d5781eecd4ce99bbbd84cef210 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Tue, 27 Apr 2021 18:25:09 +0000 Subject: [PATCH 08/10] vagrant: Fix basebox having corrupt docker-compose binary This fixes the vagrant based sandbox from not working. This was particularly annoying to track down because of not having `set -x` in `setup.sh` but what looks like xtrace output in stderr. The xtrace output on stderr was actually from the `generate_certificates` container: ``` provisioner: 2021/04/26 21:22:32 [INFO] signed certificate with serial number 142120228981443865252746731124927082232998754394 provisioner: + cat provisioner: server.pem provisioner: ca.pem provisioner: + cmp provisioner: -s provisioner: bundle.pem.tmp provisioner: bundle.pem provisioner: + mv provisioner: bundle.pem.tmp provisioner: bundle.pem provisioner: Error: No such object: ==> provisioner: Clearing any previously set forwarded ports... ==> provisioner: Removing domain... The SSH command responded with a non-zero exit status. Vagrant assumes that this means the command failed. The output for this command should be in the log above. Please read the output to determine what went wrong. ``` I ended up doubting the `if ! cmp` blocks until I added `set -euxo pipefail` and the issue was pretty obviously in docker-compose land. ``` $ vagrant destroy -f; vagrant up provisioner ==> worker: Domain is not created. Please run `vagrant up` first. ==> provisioner: Domain is not created. Please run `vagrant up` first. Bringing machine 'provisioner' up with 'libvirt' provider... ==> provisioner: Checking if box 'tinkerbelloss/sandbox-ubuntu1804' version '0.1.0' is up to date... ==> provisioner: Creating image (snapshot of base box volume). ==> provisioner: Creating domain with the following settings... ... provisioner: 2021/04/27 18:20:13 [INFO] signed certificate with serial number 138080403356863347716407921665793913032297783787 provisioner: + cat server.pem ca.pem provisioner: + cmp -s bundle.pem.tmp bundle.pem provisioner: + mv bundle.pem.tmp bundle.pem provisioner: + local certs_dir=/etc/docker/certs.d/192.168.1.1 provisioner: + cmp --quiet /vagrant/deploy/state/certs/ca.pem /vagrant/deploy/state/webroot/workflow/ca.pem provisioner: + cp /vagrant/deploy/state/certs/ca.pem /vagrant/deploy/state/webroot/workflow/ca.pem provisioner: + cmp --quiet /vagrant/deploy/state/certs/ca.pem /etc/docker/certs.d/192.168.1.1/tinkerbell.crt provisioner: + [[ -d /etc/docker/certs.d/192.168.1.1/ ]] provisioner: + cp /vagrant/deploy/state/certs/ca.pem /etc/docker/certs.d/192.168.1.1/tinkerbell.crt provisioner: + setup_docker_registry provisioner: + local registry_images=/vagrant/deploy/state/registry provisioner: + [[ -d /vagrant/deploy/state/registry ]] provisioner: + mkdir -p /vagrant/deploy/state/registry provisioner: + start_registry provisioner: + docker-compose -f /vagrant/deploy/docker-compose.yml up --build -d registry provisioner: + check_container_status registry provisioner: + local container_name=registry provisioner: + local container_id provisioner: ++ docker-compose -f /vagrant/deploy/docker-compose.yml ps -q registry provisioner: + container_id= provisioner: + local start_moment provisioner: + local current_status provisioner: ++ docker inspect '' --format '{{ .State.StartedAt }}' provisioner: Error: No such object: provisioner: + start_moment= provisioner: + finish provisioner: + rm -rf /tmp/tmp.ve3XJ7qtgA ``` Notice that `container_id` is empty. This turns out to be because `docker-compose` is an empty file! ``` vagrant@provisioner:/vagrant/deploy$ docker-compose up --build registry vagrant@provisioner:/vagrant/deploy$ which docker-compose /usr/local/bin/docker-compose vagrant@provisioner:/vagrant/deploy$ docker-compose -h vagrant@provisioner:/vagrant/deploy$ file /usr/local/bin/docker-compose /usr/local/bin/docker-compose: empty ``` So with the following test patch: ```diff diff --git a/deploy/vagrant/scripts/tinkerbell.sh b/deploy/vagrant/scripts/tinkerbell.sh index 915f27f..dcb379c 100644 --- a/deploy/vagrant/scripts/tinkerbell.sh +++ b/deploy/vagrant/scripts/tinkerbell.sh @@ -34,6 +34,14 @@ setup_nat() ( main() ( export DEBIAN_FRONTEND=noninteractive + local name=docker-compose-$(uname -s)-$(uname -m) + local url=https://github.com/docker/compose/releases/download/1.26.0/$name + curl -fsSLO "$url" + curl -fsSLO "$url.sha256" + sha256sum -c <"$name.sha256" + chmod +x "$name" + sudo mv "$name" /usr/local/bin/docker-compose + if ! [[ -f ./.env ]]; then ./generate-env.sh eth1 >.env fi ``` We can try again and we're back to a working state: ``` $ vagrant destroy -f; vagrant up provisioner ==> worker: Domain is not created. Please run `vagrant up` first. ==> provisioner: Domain is not created. Please run `vagrant up` first. Bringing machine 'provisioner' up with 'libvirt' provider... ==> provisioner: Checking if box 'tinkerbelloss/sandbox-ubuntu1804' version '0.1.0' is up to date... ==> provisioner: Creating image (snapshot of base box volume). ==> provisioner: Creating domain with the following settings... ... provisioner: + setup_docker_registry provisioner: + local registry_images=/vagrant/deploy/state/registry provisioner: + [[ -d /vagrant/deploy/state/registry ]] provisioner: + mkdir -p /vagrant/deploy/state/registry provisioner: + start_registry provisioner: + docker-compose -f /vagrant/deploy/docker-compose.yml up --build -d registry provisioner: Creating network "deploy_default" with the default driver provisioner: Creating volume "deploy_postgres_data" with default driver provisioner: Building registry provisioner: Step 1/7 : FROM registry:2.7.1 ... provisioner: Successfully tagged deploy_registry:latest provisioner: Creating deploy_registry_1 ... Creating deploy_registry_1 ... done provisioner: + check_container_status registry provisioner: + local container_name=registry provisioner: + local container_id provisioner: ++ docker-compose -f /vagrant/deploy/docker-compose.yml ps -q registry provisioner: + container_id=2e3d9557fd4c0d7f7e1c091b957a0033d23ebb93f6c8e5cdfeb8947b2812845c ... provisioner: + sudo -iu vagrant docker login --username=admin --password-stdin 192.168.1.1 provisioner: WARNING! Your password will be stored unencrypted in /home/vagrant/.docker/config.json. provisioner: Configure a credential helper to remove this warning. See provisioner: https://docs.docker.com/engine/reference/commandline/login/#credentials-store provisioner: Login Succeeded provisioner: + set +x provisioner: NEXT: 1. Enter /vagrant/deploy and run: source ../.env; docker-compose up -d provisioner: 2. Try executing your fist workflow. provisioner: Follow the steps described in https://tinkerbell.org/examples/hello-world/ to say 'Hello World!' with a workflow. ``` :toot: Except that my results are not due to the way docker-compose is being installed at all. After still running into this issue when using a box built with the new install method I was still seeing empty docker-compose files. I ran a bunch of experiments to try and figure out what is going on. The issue is strictly in vagrant-libvirt since vagrant-virtualbox works fine. Turns out data isn't being flushed back to disk at shutdown. Both calling `sync` or writing multiple copies of the binary to the fs (3x at least) ended up working. Then I was informed of a known vagrant-libvirt issue which matches this behavior, https://github.com/vagrant-libvirt/vagrant-libvirt/issues/1013! Fixes #59 Signed-off-by: Manuel Mendez --- deploy/vagrant/basebox/ubuntu1804/provision.sh | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/deploy/vagrant/basebox/ubuntu1804/provision.sh b/deploy/vagrant/basebox/ubuntu1804/provision.sh index 6c84e60..af4373f 100644 --- a/deploy/vagrant/basebox/ubuntu1804/provision.sh +++ b/deploy/vagrant/basebox/ubuntu1804/provision.sh @@ -30,13 +30,17 @@ setup_docker() ( ; ) +# from https://docs.docker.com/compose/install/ setup_docker_compose() ( - # from https://docs.docker.com/compose/install/ - sudo curl -L \ - "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" \ - -o /usr/local/bin/docker-compose - - sudo chmod +x /usr/local/bin/docker-compose + local name url + name=docker-compose-$(uname -s)-$(uname -m) + url=https://github.com/docker/compose/releases/download/1.26.0/$name + curl -fsSLO "$url" + curl -fsSLO "$url.sha256" + sha256sum -c <"$name.sha256" + rm -f "$name.sha256" + chmod +x "$name" + sudo mv "$name" /usr/local/bin/docker-compose ) main() ( @@ -50,3 +54,4 @@ main() ( ) main +sync # do not remove! From ffbb92909bcf6bfcf3f29904b7c42b64d8b9b072 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Wed, 28 Apr 2021 20:12:51 +0000 Subject: [PATCH 09/10] setup: Add blank file check to check_command This way we can better gaurd against empty files as seen in the previous commits message. Signed-off-by: Manuel Mendez --- setup.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/setup.sh b/setup.sh index 59da9aa..8692171 100755 --- a/setup.sh +++ b/setup.sh @@ -427,13 +427,15 @@ command_exists() ( ) check_command() ( - if command_exists "$1"; then - echo "$BLANK Found prerequisite: $1" - return 0 - else - echo "$ERR Prerequisite command not installed: $1" + if ! command_exists "$1"; then + echo "$ERR Prerequisite executable command not found: $1" return 1 fi + if ! [[ -s "$(which "$1")" ]]; then + echo "$ERR Prerequisite command is an empty file: $1" + fi + echo "$BLANK Found prerequisite: $1" + return 0 ) check_prerequisites() ( From 7e2296df94832dd6ad14ba4954f66d10a91956a0 Mon Sep 17 00:00:00 2001 From: Manuel Mendez Date: Thu, 29 Apr 2021 15:16:43 +0000 Subject: [PATCH 10/10] setup: Correct misspelling fist -> first Signed-off-by: Manuel Mendez --- setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.sh b/setup.sh index 8692171..72de98b 100755 --- a/setup.sh +++ b/setup.sh @@ -479,7 +479,7 @@ check_prerequisites() ( whats_next() ( echo "$NEXT 1. Enter /vagrant/deploy and run: source ../.env; docker-compose up -d" - echo "$BLANK 2. Try executing your fist workflow." + echo "$BLANK 2. Try executing your first workflow." echo "$BLANK Follow the steps described in https://tinkerbell.org/examples/hello-world/ to say 'Hello World!' with a workflow." )