-
Notifications
You must be signed in to change notification settings - Fork 2
/
002_provision_pi
executable file
·174 lines (148 loc) · 5.86 KB
/
002_provision_pi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#!/usr/bin/env bash
set -euo pipefail -o errtrace
SSH_KEY_TO_AUTHORIZE="$HOME/.ssh/id_ed25519.pub"
SSH_KEY_TO_ADD="$HOME/standard_raspberry_pi_key/id_ed25519.pub"
OLD_HOSTNAME="raspberrypi"
NEW_HOSTNAME="$OLD_HOSTNAME"
USER_NAME=""
PASSWORD=""
GIT_USER_EMAIL=''
GIT_USER_NAME=''
ENABLE_SPI=false
PRIV_SSH_KEY_FILE=''
# Make things require as little user input as possible.
# dont warn about hostkey not existing, don't add host key to known_hosts file since this may be a short lived
# "raspberrypi.local" host if we are changing the hostname anyway. Else subsequent hosts with the same name
# will have SSH errors if another machine's host key is already present under the "rapberrypi.local" hostname.
SSH_OPTS="-o StrictHostKeyChecking=no -o 'UserKnownHostsFile /dev/null'"
usage(){
echo "Usage: $(basename "${0}") -u <USER_NAME> -p <PASSWORD> [-i <SSH_KEY_TO_AUTHORIZE>] [-j <SSH_KEY_TO_ADD>] [-h <NEW_HOSTNAME>] [-g <OLD_HOSTNAME>] [-e <GIT_USER_EMAIL>] [-f <GIT_USER_NAME>] [-s]"
echo "Run this from laptop."
echo " -u USER_NAME : User name for the raspberry pi's user account."
echo " -p PASSWORD : Password for the raspberry pi's user account."
echo " -i SSH_KEY_TO_AUTHORIZE : path to ssh key to add to authorized_keys for passwordless login on raspberry pi"
echo " Defaults to: $SSH_KEY_TO_AUTHORIZE"
echo " -j SSH_KEY_TO_ADD : path to ssh key to copy to ~/.ssh on the raspberry pi. If you specify the public"
echo " key path, the corresponding private key will also be copied and vice versa."
echo " Defaults to: $SSH_KEY_TO_ADD"
echo " -h NEW_HOSTNAME : Change the raspberry pi's hostname. Defaults to $OLD_HOSTNAME."
echo " -g OLD_HOSTNAME : Defaults to $OLD_HOSTNAME"
echo " -e GIT_USER_EMAIL : email address for git"
echo " -f GIT_USER_NAME : user name for git"
echo " -s : Enable SPI"
exit 1
}
main(){
trap 'fail $? $LINENO' ERR
parseOpts "$@"
setupSsh
provisionPi
info "\\nDone provisioning raspberry pi!"
}
parseOpts(){
while getopts ":u:p:i:j:h:g:e:f:s" opt; do
case ${opt} in
u) USER_NAME=${OPTARG} ;;
p) PASSWORD=${OPTARG} ;;
i) SSH_KEY_TO_AUTHORIZE=${OPTARG} ;;
j) SSH_KEY_TO_ADD=${OPTARG} ;;
h)
if [[ "$OPTARG" =~ ^[a-z]([a-z0-9-]*[a-z0-9])?$ ]]; then
NEW_HOSTNAME=${OPTARG}
else
warn "Invalid hostname."
usage
fi
;;
g) OLD_HOSTNAME=${OPTARG} ;;
e) GIT_USER_EMAIL=${OPTARG} ;;
f) GIT_USER_NAME=${OPTARG} ;;
s) ENABLE_SPI=true ;;
\?)
warn "Invalid option: -$OPTARG"
usage
;;
:)
warn "Option -$OPTARG requires an argument."
usage
;;
*) usage ;;
esac
done
# Validation
local has_usage_errors
has_usage_errors=false
if [ -z "$USER_NAME" ]; then
has_usage_errors=true
warn "Please supply a user name for the raspberry pi's user account with the flag: -u"
fi
if [ -z "$PASSWORD" ]; then
has_usage_errors=true
warn "Please supply a password for the raspberry pi's user account with the flag: -p"
fi
if [[ $has_usage_errors == "true" ]]; then
usage
fi
}
setupSsh(){
info "\\nAuthorizing passwordless ssh with $SSH_KEY_TO_AUTHORIZE..."
info "When asked for a password, please enter the raspberry pi's password: $PASSWORD\\n"
local hostname_for_ssh
hostname_for_ssh=$(getHostnameForSsh "$OLD_HOSTNAME")
eval "ssh-copy-id $SSH_OPTS -i $SSH_KEY_TO_AUTHORIZE $USER_NAME@$hostname_for_ssh"
if [[ ${SSH_KEY_TO_ADD} == *.pub ]]; then
PUB_SSH_KEY_TO_ADD="$SSH_KEY_TO_ADD"
PRIV_SSH_KEY_TO_ADD="${PUB_SSH_KEY_TO_ADD%.pub}"
else
PRIV_SSH_KEY_TO_ADD="$SSH_KEY_TO_ADD"
PUB_SSH_KEY_TO_ADD="$PRIV_SSH_KEY_TO_ADD".pub
fi
PRIV_SSH_KEY_FILE=$(basename "$PRIV_SSH_KEY_TO_ADD")
destination="$USER_NAME@$hostname_for_ssh:~/.ssh"
info "\\nCopying $PUB_SSH_KEY_TO_ADD and $PRIV_SSH_KEY_TO_ADD to $destination..."
eval "scp $SSH_OPTS $PUB_SSH_KEY_TO_ADD $PRIV_SSH_KEY_TO_ADD $destination"
}
provisionPi(){
info "\\nProvisioning raspberry pi..."
local hostname_for_ssh
hostname_for_ssh=$(getHostnameForSsh "$OLD_HOSTNAME")
provision_cmd="ssh $SSH_OPTS $USER_NAME@$hostname_for_ssh -- "
provision_cmd+="'curl https://raw.githubusercontent.com/dasl-/pitools/main/provision_pi > provision_pi && "
provision_cmd+="chmod a+x provision_pi && "
provision_cmd+="./provision_pi -p $PASSWORD -h $NEW_HOSTNAME -i ~/.ssh/$PRIV_SSH_KEY_FILE -e $GIT_USER_EMAIL -f $GIT_USER_NAME -r "
if [[ ${ENABLE_SPI} == "true" ]]; then
provision_cmd+="-s "
fi
provision_cmd+="'"
info "Running: $provision_cmd"
eval "$provision_cmd"
}
getHostnameForSsh(){
local hostname_for_ssh;
hostname_for_ssh=$1
# If it matches the hostname regex, assume its a hostname that we're supposed to append '.local' to.
if [[ "$hostname_for_ssh" =~ ^[a-z]([a-z0-9-]*[a-z0-9])?$ ]]; then
hostname_for_ssh="$hostname_for_ssh.local"
fi
# Otherwise, assume it's an IP address that we don't append '.local' to.
echo "$hostname_for_ssh"
}
fail(){
local exit_code=$1
local line_no=$2
local script_name
script_name=$(basename "${BASH_SOURCE[0]}")
die "Error in $script_name at line number: $line_no with exit code: $exit_code"
}
info(){
echo -e "\x1b[32m$*\x1b[0m" # green stdout
}
warn(){
echo -e "\x1b[33m$*\x1b[0m" # yellow stdout
}
die(){
echo
echo -e "\x1b[31m$*\x1b[0m" >&2 # red stderr
exit 1
}
main "$@"