Commit 17cab69f authored by Ilja's avatar Ilja
Browse files

Merge branch 'code-review' into 'master'

Code review of install script

See merge request Spctrl/neutrinet_cube_install!1
parents ddc37fbd a8ddfb1f
Pipeline #145 failed with stages
......@@ -68,32 +68,33 @@ function get_hypercube_file() {
domain_available=false
while ( ! $domain_available )
do
if [ "$(echo $domain | grep .noho.st$ || echo $domain | grep .nohost.me$ || echo $domain | grep .ynh.fr$)" != "" ]
if grep -e '.noho.st$' -e '.nohost.me$' -e '.ynh.fr$' <<< "$domain"
then # ynh dyndns
echo "you've chosen one of the subdomain. Checking availability..."
( curl -sI "https://dyndns.yunohost.org/test/$domain" | grep HTTP | grep 200 > /dev/null ) && domain_available=true \
&& echo "$domain is available!"
echo "You've chosen one of the free subdomains. Checking availability..."
if curl --fail --silent "https://dyndns.yunohost.org/test/$domain"
then
domain_available=true
else
echo
echo "$domain is not available. Please choose another domain"
echo "You can either use your own custom domain, or freely use a subdomain under one of the following doamains:"
echo " .nohost.me"
echo " .noho.st"
echo " .ynh.fr"
echo "i.e.: example.nohost.me"
read domain
fi
else # own domain
domain_available=true
fi
if (! $domain_available )
then
echo
echo "$domain is not available. Please choose another domain"
echo "You can either use your own custom domain, or freely use a subdomain under one of the following doamains:"
echo " .nohost.me"
echo " .noho.st"
echo " .ynh.fr"
echo "i.e.: example.nohost.me"
read domain
fi
done
echo
echo "Username (used to connect to the user interface and access your apps, must be composed of lowercase letters and numbers only)"
echo "i.e.: jonsnow"
read username
while [ "$username" == "" ] # TODO: test with regex
while [[ -z $username ]] # TODO: test with regex
do
echo "Please provide a username (used to connect to the user interface and access your apps, must be composed of lowercase letters and numbers only)"
echo "i.e.: jonsnow"
......@@ -104,7 +105,7 @@ function get_hypercube_file() {
echo "Firstname (mandatory, used as your firstname when you send emails)"
echo "i.e.: Jon"
read firstname
while [ "$firstname" == "" ]
while [[ -z $firstname ]] # TODO: check if there are constraints (min length, etc.)
do
echo "Please provide a firstname (mandatory, used as your firstname when you send emails)"
echo "i.e.: Jon"
......@@ -115,7 +116,7 @@ function get_hypercube_file() {
echo "Lastname (mandatory, used as your lastname when you send emails)"
echo "i.e. Snow"
read lastname
while [ "$lastname" == "" ]
while [[ -z $lastname ]] # TODO: check if there are constraints (min length, etc.)
do
echo "Please provide a lastname (mandatory, used as your lastname when you send emails)"
echo "i.e. Snow"
......@@ -123,24 +124,25 @@ function get_hypercube_file() {
done
echo
echo "user password (Use a strong password!)"
echo "see https://ssd.eff.org/en/module/creating-strong-passwords for advice"
read -s user_pwd
echo "User password (Use a strong password!)"
echo "See https://ssd.eff.org/en/module/creating-strong-passwords for advice"
read -s user_pwd # TODO: check if there are constranits (emptiness, min length, etc.), maybe ask twice the password
echo
echo "admin password (Use a strong password! This will access the admin screen of your internetcube)"
echo "see https://ssd.eff.org/en/module/creating-strong-passwords for advice"
read -s admin_pwd
echo "Admin password (Use a strong password! This will access the admin screen of your internetcube)"
echo "See https://ssd.eff.org/en/module/creating-strong-passwords for advice"
read -s admin_pwd # TODO: check if there are constraints (emptiness, min length, etc.), maybe ask twice the password
# The following should be automated
# TODO: The following should be automated
# See https://github.com/Neutrinet/scripts/tree/master/vpn for inspiration
# We could download the configuration package from the web interface?
echo
echo "You will now need to enter your neutrinet vpn certificates and credentials"
echo "If you want to reuse certificates from a previous install, you can find everything on that cube as user.crt, user.key, ca-server.crt and credentials in /etc/openvpn/keys"
echo "If you do not have an account yet, please see https://wiki.neutrinet.be/vpn/order"
echo
echo "VPN client certificate (paste all the content of client.crt below and end with a blank line): "
vpn_client_crt=$(sed '/^$/q' | sed '/^$/d')
vpn_client_crt=$(sed '/^$/q' | sed '/^$/d') # TODO: figure out this black magic
echo
echo "VPN client key (paste all the content of client.key below and end with a blank line): "
vpn_client_key=$(sed '/^$/q' | sed '/^$/d')
......@@ -160,11 +162,11 @@ function get_hypercube_file() {
echo
echo "WiFi hotspot name"
echo "i.e.: MyWunderbarNeutralNetwork"
read wifi_ssid
read wifi_ssid # TODO: check if there are constraints + emptiness
echo
echo "WiFi hotspot password"
echo "i.e.: MyWunderbarNeutralNetwork"
read -s wifi_pwd
read -s wifi_pwd # TODO: check if there are constraints + emptiness
echo
create_hypercubefile
......@@ -177,6 +179,10 @@ function create_hypercubefile() {
# Make template file
hypercubefile="install.hypercube"
vpn_client_crt="${vpn_client_crt//$'\n'/\|}"
vpn_client_key="${vpn_client_key//$'\n'/\|}"
vpn_ca_crt="${vpn_ca_crt//$'\n'/\|}"
cat > $hypercubefile << EOF
{
"vpnclient": {
......@@ -185,12 +191,12 @@ function create_hypercubefile() {
"server_proto": "udp",
"ip6_net": "",
"ip4_addr": "",
"crt_server_ca": "VPN_CA_CRT",
"crt_client": "VPN_CLIENT_CRT",
"crt_client_key": "VPN_CLIENT_KEY",
"crt_server_ca": "$vpn_ca_crt",
"crt_client": "$vpn_client_crt",
"crt_client_key": "$vpn_client_key",
"crt_client_ta": "",
"login_user": "VPN_USERNAME",
"login_passphrase": "VPN_PWD",
"login_user": "$vpn_username",
"login_passphrase": "$vpn_pwd",
"dns0": "89.234.141.66",
"dns1": "2001:913::8",
"openvpn_rm": [
......@@ -204,8 +210,8 @@ function create_hypercubefile() {
]
},
"hotspot": {
"wifi_ssid": "WIFI_SSID",
"wifi_passphrase": "WIFI_PWD",
"wifi_ssid": "$wifi_ssid",
"wifi_passphrase": "$wifi_pwd",
"ip6_net": "",
"ip6_dns0": "2001:913::8",
"ip6_dns1": "2001:910:800::40",
......@@ -215,41 +221,19 @@ function create_hypercubefile() {
"firmware_nonfree": "no"
},
"yunohost": {
"domain": "DOMAIN",
"password": "ADMIN_PWD",
"user": "USERNAME",
"user_firstname": "FIRSTNAME",
"user_lastname": "LASTNAME",
"user_password": "USER_PWD"
"domain": "$domain",
"password": "$admin_pwd",
"user": "$username",
"user_firstname": "$firstname",
"user_lastname": "$lastname",
"user_password": "$user_pwd"
},
"unix": {
"root_password": "ADMIN_PWD",
"root_password": "$admin_pwd",
"lang": "en"
}
}
EOF
# Prepare vars to replace in file
vpn_client_crt="${vpn_client_crt//$'\n'/\\|}"
vpn_client_key="${vpn_client_key//$'\n'/\\|}"
vpn_ca_crt="${vpn_ca_crt//$'\n'/\\|}"
# Replace vars in file
sed -i "s~\"VPN_CLIENT_CRT\"~\"$vpn_client_crt\"~" $hypercubefile
sed -i "s~\"VPN_CLIENT_KEY\"~\"$vpn_client_key\"~" $hypercubefile
sed -i "s~\"VPN_CA_CRT\"~\"$vpn_ca_crt\"~" $hypercubefile
sed -i "s/VPN_USERNAME/$vpn_username/g" $hypercubefile
sed -i "s/VPN_PWD/$vpn_pwd/g" $hypercubefile
sed -i "s/WIFI_SSID/$wifi_ssid/g" $hypercubefile
sed -i "s/WIFI_PWD/$wifi_pwd/g" $hypercubefile
sed -i "s/DOMAIN/$domain/g" $hypercubefile
sed -i "s/USERNAME/$username/g" $hypercubefile
sed -i "s/FIRSTNAME/$firstname/g" $hypercubefile
sed -i "s/LASTNAME/$lastname/g" $hypercubefile
sed -i "s/USER_PWD/$user_pwd/g" $hypercubefile
sed -i "s/ADMIN_PWD/$admin_pwd/g" $hypercubefile
echo "install.hypercube created"
}
......@@ -257,7 +241,7 @@ function get_image() {
echo
echo "What hardware are you installing on? lime/lime2"
read board
while [ "$board" != "lime" ] && [ "$board" != "lime2" ]
while [[ $board != "lime" && "$board" != "lime2" ]]
do
echo "This script doesn't support this. Please choose lime/lime2"
read board
......@@ -267,31 +251,74 @@ function get_image() {
}
function download_image() {
INTERNETCUBE_PREFIX="internetcube"
YUNOHOST_PREFIX="yunohost"
echo
echo "Finding image..."
image=$(ls ../cube_resources/internetcube*-$board-*.img 2> /dev/null | head -n1)
if [ -z $image ]
image=$(ls ../$CUBE_RESOURCES_LOCATION/${INTERNETCUBE_PREFIX}-${DEBIAN_CODENAME}-*-$board-*.img 2> /dev/null | head -n 1)
if [[ -z $image ]]
then
image=$(curl -s $YNH_IMG_LOCATION | grep .img.zip\" | grep "stretch" | grep $board- | perl -nle 'm/href="([^ ]*).zip"/; print $1';)
# TODO
# error if no image is found. Alternative is to use a fallback. We can also first check the folder from where it's executed. If there's a correct file there=>ask to use that one? No gpg check needed then. What if multiple images are found?
# check gpg (download it and check it during flashing with the install-sd.sh script)
echo "downloading $board image"
curl -#o "$image.zip" "$YNH_IMG_LOCATION/$image.zip" # This should have the -s option instead of -# if we make it async
image_zip=$(curl --show-error --fail --silent $YNH_IMG_LOCATION | grep "${YUNOHOST_PREFIX}-${DEBIAN_CODENAME}-[\d\.]+-$board-stable.img.zip" -Po | sort -V | tail -n 1)
image=${image_zip%.zip}
echo "Downloading $board image"
curl --show-error --fail --progress-bar --output "$image_zip" "$YNH_IMG_LOCATION/$image_zip"
echo
echo "unzipping..."
unzip "$image.zip"
rm "$image.zip"
image=$(ls *-$board-*.img | head -n1)
echo "Checking image integrity..."
image_sha256sum=$(curl --show-error --fail --silent $YNH_IMG_LOCATION/$image_zip.sha256sum || true)
if [[ -z $image_sha256sum ]] || ! sha256sum -c <<< $image_sha256sum
then
>&2 echo "WARNING: Couldn't verify integrity of $image!!!"
>&2 echo "Do you really want to continue with the installation? (yes/no)"
read continue_install
if [[ $continue_install != "yes" && $continue_install != "y" ]]
then
exit 1
fi
fi
echo
echo "Unzipping..."
unzip "$image_zip"
rm "$image_zip"
image=$(ls -t ${YUNOHOST_PREFIX}-${DEBIAN_CODENAME}-*-$board-stable.img | head -n1)
echo
echo "preparing as internetcube image..."
echo "Preparing as internetcube image..."
check_sudo
[ -d yunocube ] || git clone "$CUBE_BUILD_SCRIPT_LOCATION" "yunocube" && sudo bash "yunocube/yunocube.sh" "$image"
if [[ ! -f $CUBE_BUILD_SCRIPT_NAME ]]
then
git clone ${CUBE_BUILD_SCRIPT_LOCATION} ${CUBE_BUILD_SCRIPT_DIR}
git -C ${CUBE_BUILD_SCRIPT_DIR} checkout ${CUBE_BUILD_SCRIPT_REVISION}
fi
echo
echo "Checking internetcube build script integrity..."
if ! sha256sum -c <<< "$CUBE_BUILD_SCRIPT_SHA256SUM $CUBE_BUILD_SCRIPT_NAME"
then
>&2 echo "WARNING: Couldn't check integrity of internetcube build script!!!"
>&2 echo "Do you really want to continue with the installation? (yes/no)"
read continue_install
if [[ $continue_install != "yes" && $continue_install != "y" ]]
then
exit 1
fi
fi
echo
echo "Building internetcube image..."
sudo bash $CUBE_BUILD_SCRIPT_NAME "$image"
rm "$image"
image=$(ls internetcube*-$board-*.img | head -n1)
image=${image/${YUNOHOST_PREFIX}/${INTERNETCUBE_PREFIX}}
fi
echo "We've got it!"
}
......@@ -299,51 +326,59 @@ function download_image() {
function flash_sd_card() {
echo
echo "Let's flash the SD-card!"
[ -f install-sd.sh ] || curl -so "install-sd.sh" "$INSTALL_SD_SCRIPT_LOCATION"
bash install-sd.sh -y "$hypercubefile" -f "$image"
if [[ ! -f $INSTALL_SD_SCRIPT_NAME ]]
then
download_install_sd_script
fi
"./$INSTALL_SD_SCRIPT_NAME" -y "$hypercubefile" -f "$image"
}
function prepare_cube() {
echo
echo "Alright! Time to prepare the cube!"
echo "Make sure the Cube is not connected to a power source (e.g: the power cable should be unplugged)"
echo "Assemble the board and case"
echo "Insert the WiFi antenna into the USB port of the Cube's board"
echo "Insert the SD card into your Cube"
echo "Connect your Cube to an ethernet cable that is connected to the internet"
echo "Connect the power cable to the Cube to start it"
echo "1. Assemble the board and case"
echo "2. Insert the WiFi antenna into the USB port of the Cube's board"
echo "3. Insert the SD card into your Cube"
echo "4. Connect your Cube to an ethernet cable that is connected to the internet"
echo "5. Connect the power cable to the Cube to start it"
echo "It may taken a couple of minutes before the cube has started up an is connected to the internet"
echo "Once the cube has started up, it will setup everything based on the answers that where given"
echo "Compleet setup can take up to an hour or even more. Please be patient. It should not take two hours"
echo "By the time the setup is compleet, you will be able to connect through the vpn"
echo
echo "Complete setup can take up to an hour or even more. Please be patient. It should not take two hours"
echo "By the time the setup is complete, you will be able to connect through the vpn"
echo
echo "Press ENTER when the cube is connected"
read -s
}
function search_cube() {
[ -f "install-sd.sh" ] || curl -so "install-sd.sh" "$INSTALL_SD_SCRIPT_LOCATION"
if [[ ! -f $INSTALL_SD_SCRIPT_NAME ]] # TODO: check if it's needed
then
download_install_sd_script
fi
echo
echo "Once your cube is started up, we can search for it on the local network so you can follow it's progress"
echo "Once your cube is started up, we can search for it on the local network so you can follow its progress"
echo "Note that it can take a couple of minutes before the cube is discoverable"
echo "Once found, you can follow the progress from the HyperCube Debug url which is of the form http://<local-ip>:2486/install.html"
echo "Note that even after finding it it can take a minute or so before the HyperCube Debug url works"
echo "You can also easily add the ip to your hosts file"
echo "Do you want to search for your cube on the local network? (yes/no)"
echo "Do you want to search for your cube on the local network? (yes/no)" # TODO: add default to yes in a pretty way
read search_cubes
if ! [ "$search_cubes" == "no" ]
if [[ $search_cubes != "no" ]]
then
echo "Searching for cubes"
continue_searching="yes"
while ! [ "$continue_searching" == "no" ]
while [[ $continue_searching != "no" ]]
do
bash ./install-sd.sh -l
"./$INSTALL_SD_SCRIPT_NAME" -l || true
echo "If we found it you should be able to follow the progress at the HyperCube Debug url"
echo "Do you want to continue searching? (yes/no)"
echo "Do you want to continue searching? (yes/no)" # TODO: add default to yes
read continue_searching
done
echo
echo "Ok! Note that the 'HyperCube Debug' url will be accessable up to four hours after completion"
echo "Ok! Note that the 'HyperCube Debug' url will be accessible up to four hours after completion"
fi
}
......@@ -360,38 +395,49 @@ function show_goodbye(){
}
function check_sudo() {
if ! which sudo &> /dev/null; then
echo "sudo command is required" && exit 1
if ! command -v sudo > /dev/null
then
echo "sudo command is required"
exit 1
fi
echo "This script needs a sudo access"
if ! sudo echo &> /dev/null; then
echo "sudo password is required" && exit 1
if ! sudo echo > /dev/null
then
echo "sudo password is required"
exit 1
fi
}
function exit_script() {
echo
if $DEBUG
then
echo "Debug mode: press ENTER to clean up and exit"
read -s
fi
echo "Cleaning up..."
[ $DEBUG ] && read
cd "../"
rm -rf "$TMP_DIR"
}
function prepare() {
echo "setting up the cube_resources folder"
mkdir -p cube_resources && cd cube_resources
echo "Setting up the $CUBE_RESOURCES_LOCATION folder"
mkdir -p "$CUBE_RESOURCES_LOCATION"
cd $CUBE_RESOURCES_LOCATION
echo "Downloading and preparing the lime image"
board=lime
download_image
echo "Downloading and preparing the lime2 image"
board=lime2
download_image
rm -rf yunocube
rm -rf tmp
echo "Downloading the install-sd.sh script"
curl -so "install-sd.sh" "$INSTALL_SD_SCRIPT_LOCATION"
rm -rf "$CUBE_BUILD_SCRIPT_DIR"
download_install_sd_script
}
function show_help() {
......@@ -404,17 +450,48 @@ function show_help() {
echo -e " Show this help" >&2
}
function download_install_sd_script() {
echo
echo "Downloading $INSTALL_SD_SCRIPT_NAME script..."
curl --show-error --fail --silent --output "$INSTALL_SD_SCRIPT_NAME" "$INSTALL_SD_SCRIPT_LOCATION/$INSTALL_SD_SCRIPT_NAME"
echo
echo "Checking integrity of $INSTALL_SD_SCRIPT_NAME..."
install_sd_md5sum=$(curl --show-error --fail --silent "$INSTALL_SD_SCRIPT_LOCATION/MD5SUMS" | grep $INSTALL_SD_SCRIPT_NAME || true)
if [[ -z $install_sd_md5sum ]] || ! md5sum -c <<< $install_sd_md5sum
then
>&2 echo "WARNING: Cannot verify the integrity of $INSTALL_SD_SCRIPT_NAME!!!"
>&2 echo "Do you really want to continue with the installation? (yes/no)"
read continue_install
if [[ $continue_install != "yes" ]] || [[ $continue_install != "y" ]]
then
exit 1
fi
fi
chmod u+x "$INSTALL_SD_SCRIPT_NAME"
}
#=================================================
# GLOBAL VARIABLES
#=================================================
YNH_IMG_LOCATION="https://build.yunohost.org"
CUBE_BUILD_SCRIPT_LOCATION="https://github.com/labriqueinternet/build.labriqueinter.net"
INSTALL_SD_SCRIPT_LOCATION="https://raw.githubusercontent.com/labriqueinternet/labriqueinter.net/master/install-sd.sh"
CUBE_BUILD_SCRIPT_LOCATION="https://github.com/labriqueinternet/build.labriqueinter.net.git"
CUBE_BUILD_SCRIPT_REVISION="9dad8a5a5e6c3127b756383f94027e7b595a89a1"
CUBE_BUILD_SCRIPT_DIR="yunocube"
CUBE_BUILD_SCRIPT_NAME="${CUBE_BUILD_SCRIPT_DIR}/yunocube.sh"
CUBE_BUILD_SCRIPT_SHA256SUM="a942ec46c7c2c6ad8e04219519a838f784465fe5fa65a1ccc1f2438ae08413be"
INSTALL_SD_SCRIPT_LOCATION="https://repo.labriqueinter.net"
INSTALL_SD_SCRIPT_NAME="install-sd.sh"
CUBE_RESOURCES_LOCATION="cube_resources"
DEBIAN_CODENAME="stretch"
#=================================================
# GET OPTIONS
#=================================================
DEBUG=false
while getopts "dhp" opt; do
case $opt in
d) DEBUG=true;;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment