From 980b83b124c02bb4380f5fbd516f92e930d9d6af Mon Sep 17 00:00:00 2001 From: H8H Date: Thu, 21 Aug 2014 03:09:09 +0200 Subject: [PATCH 1/8] Added dialogs, so that the setup.sh can ask the user any questions even when its piped; Added additional email valdidation for the last step --- setup/functions.sh | 25 ++++++++ setup/start.sh | 145 +++++++++++++++++++++++++++------------------ 2 files changed, 111 insertions(+), 59 deletions(-) diff --git a/setup/functions.sh b/setup/functions.sh index 0140baf7..6d4087b8 100644 --- a/setup/functions.sh +++ b/setup/functions.sh @@ -127,3 +127,28 @@ function ufw_allow { function restart_service { hide_output service $1 restart } + +## Dialog Functions ## +function message_box { + dialog --title "$1" --msgbox "$2" 0 0 +} + +function input_box { + TMP=`mktemp` + dialog --title "$1" --inputbox "$2" 0 0 "$3" 2>$TMP + + respose=$? + + case $respose in + 0) + result=$(<$TMP) + ;; + 1) + exit + ;; + 255) + exit + esac + + rm $TMP +} diff --git a/setup/start.sh b/setup/start.sh index c210e222..6d676dff 100755 --- a/setup/start.sh +++ b/setup/start.sh @@ -38,12 +38,11 @@ fi if [ -t 0 ]; then # In an interactive shell... - echo - echo "Hello and thanks for deploying a Mail-in-a-Box!" - echo "-----------------------------------------------" - echo - echo "I'm going to ask you a few questions. To change your answers later," - echo "later, just re-run this script." + # Install dialog + echo "Preparing installation ... " + apt_install dialog + message_box "Hello and thanks for deploying a Mail-in-a-Box!" \ + "I'm going to ask you a few questions. To change your answers later, just re-run this script." fi # Recall the last settings used if we're running this a second time. @@ -64,24 +63,26 @@ if [ -z "$PRIMARY_HOSTNAME" ]; then if [ -z "$DEFAULT_PRIMARY_HOSTNAME" ]; then # This is the first run. Ask the user for his email address so we can # provide the best default for the box's hostname. - echo - echo "What email address are you setting this box up to manage?" - echo "" - echo "The part after the @-sign must be a domain name or subdomain" - echo "that you control. You can add other email addresses to this" - echo "box later (including email addresses on other domain names" - echo "or subdomains you control)." - echo - echo "We've guessed an email address. Backspace it and type in what" - echo "you really want." - echo - read -e -i "me@`get_default_hostname`" -p "Email Address: " EMAIL_ADDR + input_box "What email address are you setting this box up to manage?" \ + "The part after the @-sign must be a domain name or subdomain + \nthat you control. You can add other email addresses to this + \nbox later (including email addresses on other domain names + \nor subdomains you control).\n + \nWe've guessed an email address. Backspace it and type in what + \nyou really want.\n + \nEmail Address (me@`get_default_hostname`): " + + if [ -z "$result" ]; then + EMAIL_ADDR=me@`get_default_hostname` + else + EMAIL_ADDR=$result + fi while ! management/mailconfig.py validate-email "$EMAIL_ADDR" do - echo "That's not a valid email address." - echo - read -e -i "$EMAIL_ADDR" -p "Email Address: " EMAIL_ADDR + input_box "What email address are you setting this box up to manage?" \ + "That's not a valid email address." $EMAIL_ADDR + EMAIL_ADDR=$result done # Take the part after the @-sign as the user's domain name, and add @@ -89,17 +90,19 @@ if [ -z "$PRIMARY_HOSTNAME" ]; then DEFAULT_PRIMARY_HOSTNAME=box.$(echo $EMAIL_ADDR | sed 's/.*@//') fi - echo - echo "This box needs a name, called a 'hostname'. The name will form a part" - echo "of the box's web address." - echo - echo "We recommend that the name be a subdomain of the domain in your email" - echo "address, so we're suggesting $DEFAULT_PRIMARY_HOSTNAME." - echo - echo "You can change it, but we recommend you don't." - echo + input_box "Hostname" \ + "This box needs a name, called a 'hostname'. The name will form a part + \nof the box's web address.\n + \nWe recommend that the name be a subdomain of the domain in your email + \naddress, so we're suggesting $DEFAULT_PRIMARY_HOSTNAME. + \nYou can change it, but we recommend you don't.\n + \nHostname ($DEFAULT_PRIMARY_HOSTNAME): " - read -e -i "$DEFAULT_PRIMARY_HOSTNAME" -p "Hostname: " PRIMARY_HOSTNAME + if [ -z "$result" ]; then + PRIMARY_HOSTNAME=$DEFAULT_PRIMARY_HOSTNAME + else + PRIMARY_HOSTNAME=$result + fi fi # If the machine is behind a NAT, inside a VM, etc., it may not know @@ -125,11 +128,16 @@ if [ -z "$PUBLIC_IP" ]; then fi if [ -z "$PUBLIC_IP" ]; then - echo - echo "Enter the public IP address of this machine, as given to you by your ISP." - echo + input_box "Your public IP address" \ + "Enter the public IP address of this machine, + as given to you by your ISP.\n + \nPublic IP ($DEFAULT_PUBLIC_IP): " - read -e -i "$DEFAULT_PUBLIC_IP" -p "Public IP: " PUBLIC_IP + if [ -z "$result" ]; then + PUBLIC_IP=$DEFAULT_PUBLIC_IP + else + PUBLIC_IP=$result + fi fi fi @@ -151,13 +159,16 @@ if [ -z "$PUBLIC_IPV6" ]; then fi if [[ -z "$PUBLIC_IPV6" && $MATCHED == 0 ]]; then - echo - echo "Optional:" - echo "Enter the public IPv6 address of this machine, as given to you by your ISP." - echo "Leave blank if the machine does not have an IPv6 address." - echo + input_box "IPv6 Optional" \ + "Enter the public IPv6 address of this machine, as given to you by your ISP. + \nLeave blank if the machine does not have an IPv6 address.\n + \nPublic IPv6 ($DEFAULT_PUBLIC_IPV6): " - read -e -i "$DEFAULT_PUBLIC_IPV6" -p "Public IPv6: " PUBLIC_IPV6 + if [ -z "$result" ]; then + PUBLIC_IPV6=$DEFAULT_PUBLIC_IPV6 + else + PUBLIC_IPV6=$result + fi fi fi @@ -171,13 +182,11 @@ if [ -z "$PRIVATE_IPV6" ]; then PRIVATE_IPV6=$(get_default_privateip 6) fi if [[ -z "$PRIVATE_IP" && -z "$PRIVATE_IPV6" ]]; then - echo - echo "I could not determine the IP or IPv6 address of the network inteface" - echo "for connecting to the Internet. Setup must stop." - echo - hostname -I - route - echo + message_box "Error" \ + "I could not determine the IP or IPv6 address of the network inteface + \nfor connecting to the Internet. Setup must stop.\n + `hostname -I`\n + `route`" exit fi @@ -190,19 +199,25 @@ fi if [ ! -z "$DEFAULT_STORAGE_ROOT" ] && [ ! -z "$DEFAULT_CSR_COUNTRY" ] && [ -f $DEFAULT_STORAGE_ROOT/ssl/ssl_cert_sign_req.csr ]; then CSR_COUNTRY=$DEFAULT_CSR_COUNTRY fi + if [ -z "$CSR_COUNTRY" ]; then - echo - echo "Enter the two-letter, uppercase country code for where you" - echo "live or where your organization is based. (This is used to" - echo "create an SSL certificate.)" - echo + input_box "Country Code" \ + "Enter the two-letter, uppercase country code for where you + \nlive or where your organization is based. (This is used to + \ncreate an SSL certificate.)\n + \nCountry Code ($DEFAULT_CSR_COUNTRY): " + + if [ -z "$result" ]; then + CSR_COUNTRY=$DEFAULT_CSR_COUNTRY + else + CSR_COUNTRY=$result + fi #if [ -z "$DEFAULT_CSR_COUNTRY" ]; then # # set a default on first run # DEFAULT_CSR_COUNTRY=...? #fi - read -e -i "$DEFAULT_CSR_COUNTRY" -p "Country Code: " CSR_COUNTRY fi # Automatic configuration, e.g. as used in our Vagrant configuration. @@ -292,12 +307,24 @@ if [ -z "`tools/mail.py user`" ]; then if [ -z "$EMAIL_ADDR" ]; then # In an interactive shell, ask the user for an email address. if [ -t 0 ]; then - echo - echo "Let's create your first mail user." - read -e -i "user@$PRIMARY_HOSTNAME" -p "Email Address: " EMAIL_ADDR + input_box "Create your first mail user" \ + "Let's create your first mail user.\n + \nEmail Address (user@$PRIMARY_HOSTNAME): " - # But in a non-interactive shell, just make something up. This - # is normally for testing. + if [ -z "$result" ]; then + EMAIL_ADDR=me@`get_default_hostname` + else + EMAIL_ADDR=$result + fi + + while ! management/mailconfig.py validate-email "$EMAIL_ADDR" + do + input_box "What email address are you setting this box up to manage?"\ + "That's not a valid email address." $EMAIL_ADDR + EMAIL_ADDR=$result + done + # But in a non-interactive shell, just make something up. + # This is normally for testing. else # Use me@PRIMARY_HOSTNAME EMAIL_ADDR=me@$PRIMARY_HOSTNAME From 7ea4d33e061eb51432221d227bd8c50c9645d238 Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Thu, 21 Aug 2014 15:52:19 +0000 Subject: [PATCH 2/8] simplify the input_box function --- setup/functions.sh | 24 ++----- setup/start.sh | 166 +++++++++++++++++++++++++-------------------- 2 files changed, 99 insertions(+), 91 deletions(-) diff --git a/setup/functions.sh b/setup/functions.sh index 6d4087b8..67272336 100644 --- a/setup/functions.sh +++ b/setup/functions.sh @@ -134,21 +134,11 @@ function message_box { } function input_box { - TMP=`mktemp` - dialog --title "$1" --inputbox "$2" 0 0 "$3" 2>$TMP - - respose=$? - - case $respose in - 0) - result=$(<$TMP) - ;; - 1) - exit - ;; - 255) - exit - esac - - rm $TMP + # input_box "title" "prompt" "defaultvalue" VARIABLE + # The user's input will be stored in the variable VARIABLE. + # The exit code from dialog will be stored in VARIABLE_EXITCODE. + declare -n result=$4 + declare -n result_code=$4_EXITCODE + result=$(dialog --stdout --title "$1" --inputbox "$2" 0 0 "$3") + result_code=$? } diff --git a/setup/start.sh b/setup/start.sh index 6d676dff..92326f96 100755 --- a/setup/start.sh +++ b/setup/start.sh @@ -38,11 +38,14 @@ fi if [ -t 0 ]; then # In an interactive shell... - # Install dialog - echo "Preparing installation ... " + # Install 'dialog' so we can ask the user questions. The original motivation for + # this was being able to ask the user for input even if stdin has been redirected, + # e.g. if we piped a bootstrapping install script to bash to get started. apt_install dialog - message_box "Hello and thanks for deploying a Mail-in-a-Box!" \ - "I'm going to ask you a few questions. To change your answers later, just re-run this script." + message_box "Mail-in-a-Box Installation" \ + "Hello and thanks for deploying a Mail-in-a-Box! + \n\nI'm going to ask you a few questions. + \n\nTo change your answers later, just re-run this script." fi # Recall the last settings used if we're running this a second time. @@ -63,26 +66,32 @@ if [ -z "$PRIMARY_HOSTNAME" ]; then if [ -z "$DEFAULT_PRIMARY_HOSTNAME" ]; then # This is the first run. Ask the user for his email address so we can # provide the best default for the box's hostname. - input_box "What email address are you setting this box up to manage?" \ - "The part after the @-sign must be a domain name or subdomain - \nthat you control. You can add other email addresses to this - \nbox later (including email addresses on other domain names - \nor subdomains you control).\n - \nWe've guessed an email address. Backspace it and type in what - \nyou really want.\n - \nEmail Address (me@`get_default_hostname`): " + input_box "Your Email Address" \ +"What email address are you setting this box up to manage? +\n\nThe part after the @-sign must be a domain name or subdomain +that you control. You can add other email addresses to this +box later (including email addresses on other domain names +or subdomains you control). +\n\nWe've guessed an email address. Backspace it and type in what +you really want. +\n\nEmail Address:" \ + me@`get_default_hostname` \ + EMAIL_ADDR - if [ -z "$result" ]; then - EMAIL_ADDR=me@`get_default_hostname` - else - EMAIL_ADDR=$result + if [ -z "$EMAIL_ADDR" ]; then + # user hit ESC/cancel + exit fi - while ! management/mailconfig.py validate-email "$EMAIL_ADDR" do - input_box "What email address are you setting this box up to manage?" \ - "That's not a valid email address." $EMAIL_ADDR - EMAIL_ADDR=$result + input_box "Your Email Address" \ + "That's not a valid email address.\n\nWhat email address are you setting this box up to manage?" \ + $EMAIL_ADDR \ + EMAIL_ADDR + if [ -z "$EMAIL_ADDR" ]; then + # user hit ESC/cancel + exit + fi done # Take the part after the @-sign as the user's domain name, and add @@ -91,17 +100,17 @@ if [ -z "$PRIMARY_HOSTNAME" ]; then fi input_box "Hostname" \ - "This box needs a name, called a 'hostname'. The name will form a part - \nof the box's web address.\n - \nWe recommend that the name be a subdomain of the domain in your email - \naddress, so we're suggesting $DEFAULT_PRIMARY_HOSTNAME. - \nYou can change it, but we recommend you don't.\n - \nHostname ($DEFAULT_PRIMARY_HOSTNAME): " +"This box needs a name, called a 'hostname'. The name will form a part of the box's web address. +\n\nWe recommend that the name be a subdomain of the domain in your email +address, so we're suggesting $DEFAULT_PRIMARY_HOSTNAME. +\n\nYou can change it, but we recommend you don't. +\n\nHostname:" \ + $DEFAULT_PRIMARY_HOSTNAME \ + PRIMARY_HOSTNAME - if [ -z "$result" ]; then - PRIMARY_HOSTNAME=$DEFAULT_PRIMARY_HOSTNAME - else - PRIMARY_HOSTNAME=$result + if [ -z "$PRIMARY_HOSTNAME" ]; then + # user hit ESC/cancel + exit fi fi @@ -128,15 +137,15 @@ if [ -z "$PUBLIC_IP" ]; then fi if [ -z "$PUBLIC_IP" ]; then - input_box "Your public IP address" \ - "Enter the public IP address of this machine, - as given to you by your ISP.\n - \nPublic IP ($DEFAULT_PUBLIC_IP): " + input_box "Public IP Address" \ + "Enter the public IP address of this machine, as given to you by your ISP. + \n\nPublic IP address:" \ + $DEFAULT_PUBLIC_IP \ + PUBLIC_IP - if [ -z "$result" ]; then - PUBLIC_IP=$DEFAULT_PUBLIC_IP - else - PUBLIC_IP=$result + if [ -z "$PUBLIC_IP" ]; then + # user hit ESC/cancel + exit fi fi fi @@ -159,15 +168,16 @@ if [ -z "$PUBLIC_IPV6" ]; then fi if [[ -z "$PUBLIC_IPV6" && $MATCHED == 0 ]]; then - input_box "IPv6 Optional" \ - "Enter the public IPv6 address of this machine, as given to you by your ISP. - \nLeave blank if the machine does not have an IPv6 address.\n - \nPublic IPv6 ($DEFAULT_PUBLIC_IPV6): " + input_box "IPv6 Address (Optional)" \ + "Enter the public IPv6 address of this machine, as given to you by your ISP. + \n\nLeave blank if the machine does not have an IPv6 address. + \n\nPublic IPv6 address:" + $DEFAULT_PUBLIC_IPV6 \ + PUBLIC_IPV6 - if [ -z "$result" ]; then - PUBLIC_IPV6=$DEFAULT_PUBLIC_IPV6 - else - PUBLIC_IPV6=$result + if [ ! $PUBLIC_IPV6_EXITCODE ]; then + # user hit ESC/cancel + exit fi fi fi @@ -182,11 +192,13 @@ if [ -z "$PRIVATE_IPV6" ]; then PRIVATE_IPV6=$(get_default_privateip 6) fi if [[ -z "$PRIVATE_IP" && -z "$PRIVATE_IPV6" ]]; then - message_box "Error" \ - "I could not determine the IP or IPv6 address of the network inteface - \nfor connecting to the Internet. Setup must stop.\n - `hostname -I`\n - `route`" + echo + echo "I could not determine the IP or IPv6 address of the network inteface" + echo "for connecting to the Internet. Setup must stop." + echo + hostname -I + route + echo exit fi @@ -201,23 +213,22 @@ if [ ! -z "$DEFAULT_STORAGE_ROOT" ] && [ ! -z "$DEFAULT_CSR_COUNTRY" ] && [ -f $ fi if [ -z "$CSR_COUNTRY" ]; then - input_box "Country Code" \ - "Enter the two-letter, uppercase country code for where you - \nlive or where your organization is based. (This is used to - \ncreate an SSL certificate.)\n - \nCountry Code ($DEFAULT_CSR_COUNTRY): " - - if [ -z "$result" ]; then - CSR_COUNTRY=$DEFAULT_CSR_COUNTRY - else - CSR_COUNTRY=$result - fi - #if [ -z "$DEFAULT_CSR_COUNTRY" ]; then # # set a default on first run # DEFAULT_CSR_COUNTRY=...? #fi + input_box "Country Code" \ +"Enter the two-letter, uppercase country code for where you live or where your +organization is based. (This is used to create an SSL certificate.) +\n\nCountry Code:" \ + $DEFAULT_CSR_COUNTRY \ + CSR_COUNTRY + + if [ -z "$CSR_COUNTRY" ]; then + # user hit ESC/cancel + exit + fi fi # Automatic configuration, e.g. as used in our Vagrant configuration. @@ -307,22 +318,29 @@ if [ -z "`tools/mail.py user`" ]; then if [ -z "$EMAIL_ADDR" ]; then # In an interactive shell, ask the user for an email address. if [ -t 0 ]; then - input_box "Create your first mail user" \ - "Let's create your first mail user.\n - \nEmail Address (user@$PRIMARY_HOSTNAME): " + input_box "Mail Account" \ + "Let's create your first mail account. + \n\nWhat email address do you want?" \ + me@`get_default_hostname` \ + EMAIL_ADDR - if [ -z "$result" ]; then - EMAIL_ADDR=me@`get_default_hostname` - else - EMAIL_ADDR=$result + if [ -z "$EMAIL_ADDR" ]; then + # user hit ESC/cancel + exit fi - while ! management/mailconfig.py validate-email "$EMAIL_ADDR" do - input_box "What email address are you setting this box up to manage?"\ - "That's not a valid email address." $EMAIL_ADDR - EMAIL_ADDR=$result + input_box "Mail Account" \ + "That's not a valid email address. + \n\nWhat email address do you want?" \ + $EMAIL_ADDR \ + EMAIL_ADDR + if [ -z "$EMAIL_ADDR" ]; then + # user hit ESC/cancel + exit + fi done + # But in a non-interactive shell, just make something up. # This is normally for testing. else From 7e8e1049647ef0fa905de404052c100c5fc8ac38 Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Thu, 21 Aug 2014 17:19:22 +0000 Subject: [PATCH 3/8] when asking for a CSR country code, give the user a list --- setup/csr_country_codes.tsv | 253 ++++++++++++++++++++++++++++++++++++ setup/functions.sh | 11 ++ setup/start.sh | 18 +-- 3 files changed, 273 insertions(+), 9 deletions(-) create mode 100644 setup/csr_country_codes.tsv diff --git a/setup/csr_country_codes.tsv b/setup/csr_country_codes.tsv new file mode 100644 index 00000000..3f8f6586 --- /dev/null +++ b/setup/csr_country_codes.tsv @@ -0,0 +1,253 @@ +# This list is derived from https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2. +# The columns are ISO_3166-1_alpha-2 code, display name, Wikipedia page name. +# The top 20 countries by number of Internet users are grouped first, see +# https://en.wikipedia.org/wiki/List_of_countries_by_number_of_Internet_users. +BR Brazil +CA Canada +CN China +EG Egypt +FR France +DE Germany +IN India +ID Indonesia +IT Italy +JP Japan +MX Mexico +NG Nigeria +PH Philippines +RU Russian Federation Russia +ES Spain +KR South Korea +TR Turkey +GB United Kingdom +US United States +VN Vietnam +AD Andorra +AE United Arab Emirates +AF Afghanistan +AG Antigua and Barbuda +AI Anguilla +AL Albania +AM Armenia +AO Angola +AQ Antarctica +AR Argentina +AS American Samoa +AT Austria +AU Australia +AW Aruba +AX Åland Islands +AZ Azerbaijan +BA Bosnia and Herzegovina +BB Barbados +BD Bangladesh +BE Belgium +BF Burkina Faso +BG Bulgaria +BH Bahrain +BI Burundi +BJ Benin +BL Saint Barthélemy +BM Bermuda +BN Brunei +BO Bolivia +BQ Bonaire, Sint Eustatius and Saba Caribbean Netherlands +BS Bahamas The Bahamas +BT Bhutan +BV Bouvet Island +BW Botswana +BY Belarus +BZ Belize +CC Cocos (Keeling) Islands +CD Congo, the Democratic Republic of the Democratic Republic of the Congo +CF Central African Republic +CG Congo Republic of the Congo +CH Switzerland +CI Côte d'Ivoire +CK Cook Islands +CL Chile +CM Cameroon +CO Colombia +CR Costa Rica +CU Cuba +CV Cabo Verde +CW Curaçao +CX Christmas Island +CY Cyprus +CZ Czech Republic +DJ Djibouti +DK Denmark +DM Dominica +DO Dominican Republic +DZ Algeria +EC Ecuador +EE Estonia +EH Western Sahara +ER Eritrea +ET Ethiopia +FI Finland +FJ Fiji +FK Falkland Islands (Malvinas) Falkland Islands +FM Federated States of Micronesia +FO Faroe Islands +GA Gabon +GD Grenada +GE Georgia Georgia (country) +GF French Guiana +GG Guernsey +GH Ghana +GI Gibraltar +GL Greenland +GM Gambia The Gambia +GN Guinea +GP Guadeloupe +GQ Equatorial Guinea +GR Greece +GS South Georgia and the South Sandwich Islands +GT Guatemala +GU Guam +GW Guinea-Bissau +GY Guyana +HK Hong Kong +HM Heard Island and McDonald Islands +HN Honduras +HR Croatia +HT Haiti +HU Hungary +IE Ireland Republic of Ireland +IL Israel +IM Isle of Man +IO British Indian Ocean Territory +IQ Iraq +IR Iran +IS Iceland +JE Jersey +JM Jamaica +JO Jordan +KE Kenya +KG Kyrgyzstan +KH Cambodia +KI Kiribati +KM Comoros +KN Saint Kitts and Nevis +KP North Korea +KW Kuwait +KY Cayman Islands +KZ Kazakhstan +LA Laos +LB Lebanon +LC Saint Lucia +LI Liechtenstein +LK Sri Lanka +LR Liberia +LS Lesotho +LT Lithuania +LU Luxembourg +LV Latvia +LY Libya +MA Morocco +MC Monaco +MD Moldova +ME Montenegro +MF Saint Martin (French part) Collectivity of Saint Martin +MG Madagascar +MH Marshall Islands +MK Macedonia Republic of Macedonia +ML Mali +MM Myanmar +MN Mongolia +MO Macao Macau +MP Northern Mariana Islands +MQ Martinique +MR Mauritania +MS Montserrat +MT Malta +MU Mauritius +MV Maldives +MW Malawi +MY Malaysia +MZ Mozambique +NA Namibia +NC New Caledonia +NE Niger +NF Norfolk Island +NI Nicaragua +NL Netherlands +NO Norway +NP Nepal +NR Nauru +NU Niue +NZ New Zealand +OM Oman +PA Panama +PE Peru +PF French Polynesia +PG Papua New Guinea +PK Pakistan +PL Poland +PM Saint Pierre and Miquelon +PN Pitcairn Pitcairn Islands +PR Puerto Rico +PS Palestine State of Palestine +PT Portugal +PW Palau +PY Paraguay +QA Qatar +RE Réunion +RO Romania +RS Serbia +RW Rwanda +SA Saudi Arabia +SB Solomon Islands +SC Seychelles +SD Sudan +SE Sweden +SG Singapore +SH Saint Helena, Ascension and Tristan da Cunha +SI Slovenia +SJ Svalbard and Jan Mayen +SK Slovakia +SL Sierra Leone +SM San Marino +SN Senegal +SO Somalia +SR Suriname +SS South Sudan +ST Sao Tome and Principe +SV El Salvador +SX Sint Maarten (Dutch part) Sint Maarten +SY Syria +SZ Swaziland +TC Turks and Caicos Islands +TD Chad +TF French Southern Territories French Southern and Antarctic Lands +TG Togo +TH Thailand +TJ Tajikistan +TK Tokelau +TL Timor-Leste East Timor +TM Turkmenistan +TN Tunisia +TO Tonga +TT Trinidad and Tobago +TV Tuvalu +TW Taiwan +TZ Tanzania +UA Ukraine +UG Uganda +UM United States Minor Outlying Islands +UY Uruguay +UZ Uzbekistan +VA Vatican City +VC Saint Vincent and the Grenadines +VE Venezuela +VG Virgin Islands, British British Virgin Islands +VI Virgin Islands, U.S. United States Virgin Islands +VU Vanuatu +WF Wallis and Futuna +WS Samoa +YE Yemen +YT Mayotte +ZA South Africa +ZM Zambia +ZW Zimbabwe diff --git a/setup/functions.sh b/setup/functions.sh index 67272336..78e67eda 100644 --- a/setup/functions.sh +++ b/setup/functions.sh @@ -142,3 +142,14 @@ function input_box { result=$(dialog --stdout --title "$1" --inputbox "$2" 0 0 "$3") result_code=$? } + +function input_menu { + # input_menu "title" "prompt" "tag item tag item" VARIABLE + # The user's input will be stored in the variable VARIABLE. + # The exit code from dialog will be stored in VARIABLE_EXITCODE. + declare -n result=$4 + declare -n result_code=$4_EXITCODE + local IFS=^$'\n' + result=$(dialog --stdout --title "$1" --menu "$2" 0 0 0 $3) + result_code=$? +} diff --git a/setup/start.sh b/setup/start.sh index 92326f96..8260ca38 100755 --- a/setup/start.sh +++ b/setup/start.sh @@ -213,16 +213,16 @@ if [ ! -z "$DEFAULT_STORAGE_ROOT" ] && [ ! -z "$DEFAULT_CSR_COUNTRY" ] && [ -f $ fi if [ -z "$CSR_COUNTRY" ]; then - #if [ -z "$DEFAULT_CSR_COUNTRY" ]; then - # # set a default on first run - # DEFAULT_CSR_COUNTRY=...? - #fi + # Get a list of country codes. Separate codes from country names with a ^. + # The input_menu function modifies shell word expansion to ignore spaces + # (since country names can have spaces) and use ^ instead. + country_code_list=$(grep -v "^#" setup/csr_country_codes.tsv | sed "s/\(..\)\t\([^\t]*\).*/\1^\2/") - input_box "Country Code" \ -"Enter the two-letter, uppercase country code for where you live or where your -organization is based. (This is used to create an SSL certificate.) -\n\nCountry Code:" \ - $DEFAULT_CSR_COUNTRY \ + input_menu "Country Code" \ + "Choose the country where you live or where your organization is based. + \n\n(This is used to create an SSL certificate.) + \n\nCountry Code:" \ + "$country_code_list" \ CSR_COUNTRY if [ -z "$CSR_COUNTRY" ]; then From 76dcab31398036b74fb9819ce66369efbb8979ad Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Thu, 21 Aug 2014 17:21:41 +0000 Subject: [PATCH 4/8] now that we use `dialog` for input we can pipe the bootstrap script to bash --- setup/bootstrap.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/setup/bootstrap.sh b/setup/bootstrap.sh index 7bc4ccf7..5d96646c 100755 --- a/setup/bootstrap.sh +++ b/setup/bootstrap.sh @@ -2,11 +2,7 @@ ######################################################### # This script is intended to be run like this: # -# wget https://raw.githubusercontent.com/mail-in-a-box/mailinabox/master/setup/bootstrap.sh -# sudo bash bootstrap.sh -# -# We can't pipe directly to bash because setup/start.sh -# asks for user input on stdin. +# wget https://.../bootstrap.sh | sudo bash # ######################################################### From 9576594cfef572556e62eb90dd8e938d033fab7e Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Thu, 21 Aug 2014 17:23:47 +0000 Subject: [PATCH 5/8] bootstrap script should check out a particular tag rather than master --- setup/bootstrap.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/setup/bootstrap.sh b/setup/bootstrap.sh index 5d96646c..21575ccb 100755 --- a/setup/bootstrap.sh +++ b/setup/bootstrap.sh @@ -6,6 +6,8 @@ # ######################################################### +TAG=14.08-beta + # Are we running as root? if [[ $EUID -ne 0 ]]; then echo "This script must be run as root. Did you leave out sudo?" @@ -19,14 +21,16 @@ cd if [ ! -d mailinabox ]; then echo Downloading Mail-in-a-Box . . . apt-get -q -q install -y git - git clone -q --depth 1 -b master https://github.com/mail-in-a-box/mailinabox + git clone -q https://github.com/mail-in-a-box/mailinabox cd mailinabox + git checkout -q $TAG # If it does exist, update it. else echo Updating Mail-in-a-Box . . . cd mailinabox - if ! git pull -q --ff-only; then + git fetch + if ! git checkout -q $TAG; then echo "Update failed. Did you modify something in `pwd`?" exit fi From 4ed69cbae59e39fecfb71d6c30d49cc1e2b886d8 Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Mon, 25 Aug 2014 07:54:11 -0400 Subject: [PATCH 6/8] replace '-t 0' test with an environment variable since '-t 0' is false when standard input has been redirected and doesn't tell us whether or not we can use dialog for input, but Vagrant must be non-interactive --- Vagrantfile | 1 + setup/start.sh | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index ea8464dd..2a21dd08 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -18,6 +18,7 @@ Vagrant.configure("2") do |config| # machine figure out its own public IP and it'll take a # subdomain on our justtesting.email domain so we can get # started quickly. + export NONINTERACTIVE=1 export PUBLIC_IP=auto export PUBLIC_IPV6=auto export PRIMARY_HOSTNAME=auto-easy diff --git a/setup/start.sh b/setup/start.sh index 8260ca38..ab9c5f25 100755 --- a/setup/start.sh +++ b/setup/start.sh @@ -36,11 +36,12 @@ if [ ! -d /vagrant ]; then fi fi -if [ -t 0 ]; then - # In an interactive shell... +if [ -z "$NONINTERACTIVE" ]; then # Install 'dialog' so we can ask the user questions. The original motivation for # this was being able to ask the user for input even if stdin has been redirected, - # e.g. if we piped a bootstrapping install script to bash to get started. + # e.g. if we piped a bootstrapping install script to bash to get started. In that + # case, the nifty '[ -t 0 ]' test won't work. But with Vagrant we must suppress so we + # use a shell flag instead. apt_install dialog message_box "Mail-in-a-Box Installation" \ "Hello and thanks for deploying a Mail-in-a-Box! @@ -317,7 +318,7 @@ if [ -z "`tools/mail.py user`" ]; then # If we didn't ask for an email address at the start, do so now. if [ -z "$EMAIL_ADDR" ]; then # In an interactive shell, ask the user for an email address. - if [ -t 0 ]; then + if [ -z "$NONINTERACTIVE" ]; then input_box "Mail Account" \ "Let's create your first mail account. \n\nWhat email address do you want?" \ From faf6f87a63f2405006751b0b7c2d3045a088f5a2 Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Mon, 25 Aug 2014 08:09:37 -0400 Subject: [PATCH 7/8] move the user-interactive questions and other parts of start.sh into new files --- setup/firstuser.sh | 57 ++++++++++ setup/preflight.sh | 29 +++++ setup/questions.sh | 182 +++++++++++++++++++++++++++++ setup/start.sh | 278 ++------------------------------------------- 4 files changed, 277 insertions(+), 269 deletions(-) create mode 100644 setup/firstuser.sh create mode 100644 setup/preflight.sh create mode 100644 setup/questions.sh diff --git a/setup/firstuser.sh b/setup/firstuser.sh new file mode 100644 index 00000000..c1e2d6cb --- /dev/null +++ b/setup/firstuser.sh @@ -0,0 +1,57 @@ +# If there aren't any mail users yet, create one. +if [ -z "`tools/mail.py user`" ]; then + # The outut of "tools/mail.py user" is a list of mail users. If there + # aren't any yet, it'll be empty. + + # If we didn't ask for an email address at the start, do so now. + if [ -z "$EMAIL_ADDR" ]; then + # In an interactive shell, ask the user for an email address. + if [ -z "$NONINTERACTIVE" ]; then + input_box "Mail Account" \ + "Let's create your first mail account. + \n\nWhat email address do you want?" \ + me@`get_default_hostname` \ + EMAIL_ADDR + + if [ -z "$EMAIL_ADDR" ]; then + # user hit ESC/cancel + exit + fi + while ! management/mailconfig.py validate-email "$EMAIL_ADDR" + do + input_box "Mail Account" \ + "That's not a valid email address. + \n\nWhat email address do you want?" \ + $EMAIL_ADDR \ + EMAIL_ADDR + if [ -z "$EMAIL_ADDR" ]; then + # user hit ESC/cancel + exit + fi + done + + # But in a non-interactive shell, just make something up. + # This is normally for testing. + else + # Use me@PRIMARY_HOSTNAME + EMAIL_ADDR=me@$PRIMARY_HOSTNAME + EMAIL_PW=1234 + echo + echo "Creating a new administrative mail account for $EMAIL_ADDR with password $EMAIL_PW." + echo + fi + else + echo + echo "Okay. I'm about to set up $EMAIL_ADDR for you. This account will also" + echo "have access to the box's control panel." + fi + + # Create the user's mail account. This will ask for a password if none was given above. + tools/mail.py user add $EMAIL_ADDR $EMAIL_PW + + # Make it an admin. + hide_output tools/mail.py user make-admin $EMAIL_ADDR + + # Create an alias to which we'll direct all automatically-created administrative aliases. + tools/mail.py alias add administrator@$PRIMARY_HOSTNAME $EMAIL_ADDR +fi \ No newline at end of file diff --git a/setup/preflight.sh b/setup/preflight.sh new file mode 100644 index 00000000..742d6db9 --- /dev/null +++ b/setup/preflight.sh @@ -0,0 +1,29 @@ +# Are we running as root? +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root. Please re-run like this:" + echo + echo "sudo setup/start.sh" + echo + exit +fi + +# Check that we are running on Ubuntu 14.04 LTS (or 14.04.xx). +if [ "`lsb_release -d | sed 's/.*:\s*//' | sed 's/14\.04\.[0-9]/14.04/' `" != "Ubuntu 14.04 LTS" ]; then + echo "Mail-in-a-Box only supports being installed on Ubuntu 14.04, sorry. You are running:" + echo + lsb_release -d | sed 's/.*:\s*//' + echo + echo "We can't write scripts that run on every possible setup, sorry." + exit +fi + +# Check that we have enough memory. Skip the check if we appear to be +# running inside of Vagrant, because that's really just for testing. +TOTAL_PHYSICAL_MEM=$(free -m | grep ^Mem: | sed "s/^Mem: *\([0-9]*\).*/\1/") +if [ $TOTAL_PHYSICAL_MEM -lt 768 ]; then +if [ ! -d /vagrant ]; then + echo "Your Mail-in-a-Box needs more than $TOTAL_PHYSICAL_MEM MB RAM." + echo "Please provision a machine with at least 768 MB, 1 GB recommended." + exit +fi +fi diff --git a/setup/questions.sh b/setup/questions.sh new file mode 100644 index 00000000..5d61286a --- /dev/null +++ b/setup/questions.sh @@ -0,0 +1,182 @@ +if [ -z "$NONINTERACTIVE" ]; then + # Install 'dialog' so we can ask the user questions. The original motivation for + # this was being able to ask the user for input even if stdin has been redirected, + # e.g. if we piped a bootstrapping install script to bash to get started. In that + # case, the nifty '[ -t 0 ]' test won't work. But with Vagrant we must suppress so we + # use a shell flag instead. + apt_install dialog + message_box "Mail-in-a-Box Installation" \ + "Hello and thanks for deploying a Mail-in-a-Box! + \n\nI'm going to ask you a few questions. + \n\nTo change your answers later, just re-run this script." +fi + +# The box needs a name. +if [ -z "$PRIMARY_HOSTNAME" ]; then + if [ -z "$DEFAULT_PRIMARY_HOSTNAME" ]; then + # This is the first run. Ask the user for his email address so we can + # provide the best default for the box's hostname. + input_box "Your Email Address" \ +"What email address are you setting this box up to manage? +\n\nThe part after the @-sign must be a domain name or subdomain +that you control. You can add other email addresses to this +box later (including email addresses on other domain names +or subdomains you control). +\n\nWe've guessed an email address. Backspace it and type in what +you really want. +\n\nEmail Address:" \ + me@`get_default_hostname` \ + EMAIL_ADDR + + if [ -z "$EMAIL_ADDR" ]; then + # user hit ESC/cancel + exit + fi + while ! management/mailconfig.py validate-email "$EMAIL_ADDR" + do + input_box "Your Email Address" \ + "That's not a valid email address.\n\nWhat email address are you setting this box up to manage?" \ + $EMAIL_ADDR \ + EMAIL_ADDR + if [ -z "$EMAIL_ADDR" ]; then + # user hit ESC/cancel + exit + fi + done + + # Take the part after the @-sign as the user's domain name, and add + # 'box.' to the beginning to create a default hostname for this machine. + DEFAULT_PRIMARY_HOSTNAME=box.$(echo $EMAIL_ADDR | sed 's/.*@//') + fi + + input_box "Hostname" \ +"This box needs a name, called a 'hostname'. The name will form a part of the box's web address. +\n\nWe recommend that the name be a subdomain of the domain in your email +address, so we're suggesting $DEFAULT_PRIMARY_HOSTNAME. +\n\nYou can change it, but we recommend you don't. +\n\nHostname:" \ + $DEFAULT_PRIMARY_HOSTNAME \ + PRIMARY_HOSTNAME + + if [ -z "$PRIMARY_HOSTNAME" ]; then + # user hit ESC/cancel + exit + fi +fi + +# If the machine is behind a NAT, inside a VM, etc., it may not know +# its IP address on the public network / the Internet. Ask the Internet +# and possibly confirm with user. +if [ -z "$PUBLIC_IP" ]; then + # Ask the Internet. + GUESSED_IP=$(get_publicip_from_web_service 4) + + # On the first run, if we got an answer from the Internet then don't + # ask the user. + if [[ -z "$DEFAULT_PUBLIC_IP" && ! -z "$GUESSED_IP" ]]; then + PUBLIC_IP=$GUESSED_IP + + # Otherwise on the first run at least provide a default. + elif [[ -z "$DEFAULT_PUBLIC_IP" ]]; then + DEFAULT_PUBLIC_IP=$(get_default_privateip 4) + + # On later runs, if the previous value matches the guessed value then + # don't ask the user either. + elif [ "$DEFAULT_PUBLIC_IP" == "$GUESSED_IP" ]; then + PUBLIC_IP=$GUESSED_IP + fi + + if [ -z "$PUBLIC_IP" ]; then + input_box "Public IP Address" \ + "Enter the public IP address of this machine, as given to you by your ISP. + \n\nPublic IP address:" \ + $DEFAULT_PUBLIC_IP \ + PUBLIC_IP + + if [ -z "$PUBLIC_IP" ]; then + # user hit ESC/cancel + exit + fi + fi +fi + +# Same for IPv6. But it's optional. Also, if it looks like the system +# doesn't have an IPv6, don't ask for one. +if [ -z "$PUBLIC_IPV6" ]; then + # Ask the Internet. + GUESSED_IP=$(get_publicip_from_web_service 6) + MATCHED=0 + if [[ -z "$DEFAULT_PUBLIC_IPV6" && ! -z "$GUESSED_IP" ]]; then + PUBLIC_IPV6=$GUESSED_IP + elif [[ "$DEFAULT_PUBLIC_IPV6" == "$GUESSED_IP" ]]; then + # No IPv6 entered and machine seems to have none, or what + # the user entered matches what the Internet tells us. + PUBLIC_IPV6=$GUESSED_IP + MATCHED=1 + elif [[ -z "$DEFAULT_PUBLIC_IPV6" ]]; then + DEFAULT_PUBLIC_IP=$(get_default_privateip 6) + fi + + if [[ -z "$PUBLIC_IPV6" && $MATCHED == 0 ]]; then + input_box "IPv6 Address (Optional)" \ + "Enter the public IPv6 address of this machine, as given to you by your ISP. + \n\nLeave blank if the machine does not have an IPv6 address. + \n\nPublic IPv6 address:" + $DEFAULT_PUBLIC_IPV6 \ + PUBLIC_IPV6 + + if [ ! $PUBLIC_IPV6_EXITCODE ]; then + # user hit ESC/cancel + exit + fi + fi +fi + +# Get the IP addresses of the local network interface(s) that are connected +# to the Internet. We need these when we want to have services bind only to +# the public network interfaces (not loopback, not tunnel interfaces). +if [ -z "$PRIVATE_IP" ]; then + PRIVATE_IP=$(get_default_privateip 4) +fi +if [ -z "$PRIVATE_IPV6" ]; then + PRIVATE_IPV6=$(get_default_privateip 6) +fi +if [[ -z "$PRIVATE_IP" && -z "$PRIVATE_IPV6" ]]; then + echo + echo "I could not determine the IP or IPv6 address of the network inteface" + echo "for connecting to the Internet. Setup must stop." + echo + hostname -I + route + echo + exit +fi + +# We need a country code to generate a certificate signing request. However +# if a CSR already exists then we won't be generating a new one and there's +# no reason to ask for the country code now. $STORAGE_ROOT has not yet been +# set so we'll check if $DEFAULT_STORAGE_ROOT and $DEFAULT_CSR_COUNTRY are +# set (the values from the current mailinabox.conf) and if the CSR exists +# in the expected location. +if [ ! -z "$DEFAULT_STORAGE_ROOT" ] && [ ! -z "$DEFAULT_CSR_COUNTRY" ] && [ -f $DEFAULT_STORAGE_ROOT/ssl/ssl_cert_sign_req.csr ]; then + CSR_COUNTRY=$DEFAULT_CSR_COUNTRY +fi + +if [ -z "$CSR_COUNTRY" ]; then + # Get a list of country codes. Separate codes from country names with a ^. + # The input_menu function modifies shell word expansion to ignore spaces + # (since country names can have spaces) and use ^ instead. + country_code_list=$(grep -v "^#" setup/csr_country_codes.tsv | sed "s/\(..\)\t\([^\t]*\).*/\1^\2/") + + input_menu "Country Code" \ + "Choose the country where you live or where your organization is based. + \n\n(This is used to create an SSL certificate.) + \n\nCountry Code:" \ + "$country_code_list" \ + CSR_COUNTRY + + if [ -z "$CSR_COUNTRY" ]; then + # user hit ESC/cancel + exit + fi +fi diff --git a/setup/start.sh b/setup/start.sh index ab9c5f25..648a3cb9 100755 --- a/setup/start.sh +++ b/setup/start.sh @@ -4,50 +4,9 @@ source setup/functions.sh # load our functions -# Check system setup. - -# Are we running as root? -if [[ $EUID -ne 0 ]]; then - echo "This script must be run as root. Please re-run like this:" - echo - echo "sudo setup/start.sh" - echo - exit -fi - -# Check that we are running on Ubuntu 14.04 LTS (or 14.04.xx). -if [ "`lsb_release -d | sed 's/.*:\s*//' | sed 's/14\.04\.[0-9]/14.04/' `" != "Ubuntu 14.04 LTS" ]; then - echo "Mail-in-a-Box only supports being installed on Ubuntu 14.04, sorry. You are running:" - echo - lsb_release -d | sed 's/.*:\s*//' - echo - echo "We can't write scripts that run on every possible setup, sorry." - exit -fi - -# Check that we have enough memory. Skip the check if we appear to be -# running inside of Vagrant, because that's really just for testing. -TOTAL_PHYSICAL_MEM=$(free -m | grep ^Mem: | sed "s/^Mem: *\([0-9]*\).*/\1/") -if [ $TOTAL_PHYSICAL_MEM -lt 768 ]; then -if [ ! -d /vagrant ]; then - echo "Your Mail-in-a-Box needs more than $TOTAL_PHYSICAL_MEM MB RAM." - echo "Please provision a machine with at least 768 MB, 1 GB recommended." - exit -fi -fi - -if [ -z "$NONINTERACTIVE" ]; then - # Install 'dialog' so we can ask the user questions. The original motivation for - # this was being able to ask the user for input even if stdin has been redirected, - # e.g. if we piped a bootstrapping install script to bash to get started. In that - # case, the nifty '[ -t 0 ]' test won't work. But with Vagrant we must suppress so we - # use a shell flag instead. - apt_install dialog - message_box "Mail-in-a-Box Installation" \ - "Hello and thanks for deploying a Mail-in-a-Box! - \n\nI'm going to ask you a few questions. - \n\nTo change your answers later, just re-run this script." -fi +# Check system setup: Are we running as root on Ubuntu 14.04 on a +# machine with enough memory? If not, this shows an error and exits. +. setup/preflight.sh # Recall the last settings used if we're running this a second time. if [ -f /etc/mailinabox.conf ]; then @@ -62,175 +21,10 @@ if [ -f /etc/mailinabox.conf ]; then rm -f /tmp/mailinabox.prev.conf fi -# The box needs a name. -if [ -z "$PRIMARY_HOSTNAME" ]; then - if [ -z "$DEFAULT_PRIMARY_HOSTNAME" ]; then - # This is the first run. Ask the user for his email address so we can - # provide the best default for the box's hostname. - input_box "Your Email Address" \ -"What email address are you setting this box up to manage? -\n\nThe part after the @-sign must be a domain name or subdomain -that you control. You can add other email addresses to this -box later (including email addresses on other domain names -or subdomains you control). -\n\nWe've guessed an email address. Backspace it and type in what -you really want. -\n\nEmail Address:" \ - me@`get_default_hostname` \ - EMAIL_ADDR - - if [ -z "$EMAIL_ADDR" ]; then - # user hit ESC/cancel - exit - fi - while ! management/mailconfig.py validate-email "$EMAIL_ADDR" - do - input_box "Your Email Address" \ - "That's not a valid email address.\n\nWhat email address are you setting this box up to manage?" \ - $EMAIL_ADDR \ - EMAIL_ADDR - if [ -z "$EMAIL_ADDR" ]; then - # user hit ESC/cancel - exit - fi - done - - # Take the part after the @-sign as the user's domain name, and add - # 'box.' to the beginning to create a default hostname for this machine. - DEFAULT_PRIMARY_HOSTNAME=box.$(echo $EMAIL_ADDR | sed 's/.*@//') - fi - - input_box "Hostname" \ -"This box needs a name, called a 'hostname'. The name will form a part of the box's web address. -\n\nWe recommend that the name be a subdomain of the domain in your email -address, so we're suggesting $DEFAULT_PRIMARY_HOSTNAME. -\n\nYou can change it, but we recommend you don't. -\n\nHostname:" \ - $DEFAULT_PRIMARY_HOSTNAME \ - PRIMARY_HOSTNAME - - if [ -z "$PRIMARY_HOSTNAME" ]; then - # user hit ESC/cancel - exit - fi -fi - -# If the machine is behind a NAT, inside a VM, etc., it may not know -# its IP address on the public network / the Internet. Ask the Internet -# and possibly confirm with user. -if [ -z "$PUBLIC_IP" ]; then - # Ask the Internet. - GUESSED_IP=$(get_publicip_from_web_service 4) - - # On the first run, if we got an answer from the Internet then don't - # ask the user. - if [[ -z "$DEFAULT_PUBLIC_IP" && ! -z "$GUESSED_IP" ]]; then - PUBLIC_IP=$GUESSED_IP - - # Otherwise on the first run at least provide a default. - elif [[ -z "$DEFAULT_PUBLIC_IP" ]]; then - DEFAULT_PUBLIC_IP=$(get_default_privateip 4) - - # On later runs, if the previous value matches the guessed value then - # don't ask the user either. - elif [ "$DEFAULT_PUBLIC_IP" == "$GUESSED_IP" ]; then - PUBLIC_IP=$GUESSED_IP - fi - - if [ -z "$PUBLIC_IP" ]; then - input_box "Public IP Address" \ - "Enter the public IP address of this machine, as given to you by your ISP. - \n\nPublic IP address:" \ - $DEFAULT_PUBLIC_IP \ - PUBLIC_IP - - if [ -z "$PUBLIC_IP" ]; then - # user hit ESC/cancel - exit - fi - fi -fi - -# Same for IPv6. But it's optional. Also, if it looks like the system -# doesn't have an IPv6, don't ask for one. -if [ -z "$PUBLIC_IPV6" ]; then - # Ask the Internet. - GUESSED_IP=$(get_publicip_from_web_service 6) - MATCHED=0 - if [[ -z "$DEFAULT_PUBLIC_IPV6" && ! -z "$GUESSED_IP" ]]; then - PUBLIC_IPV6=$GUESSED_IP - elif [[ "$DEFAULT_PUBLIC_IPV6" == "$GUESSED_IP" ]]; then - # No IPv6 entered and machine seems to have none, or what - # the user entered matches what the Internet tells us. - PUBLIC_IPV6=$GUESSED_IP - MATCHED=1 - elif [[ -z "$DEFAULT_PUBLIC_IPV6" ]]; then - DEFAULT_PUBLIC_IP=$(get_default_privateip 6) - fi - - if [[ -z "$PUBLIC_IPV6" && $MATCHED == 0 ]]; then - input_box "IPv6 Address (Optional)" \ - "Enter the public IPv6 address of this machine, as given to you by your ISP. - \n\nLeave blank if the machine does not have an IPv6 address. - \n\nPublic IPv6 address:" - $DEFAULT_PUBLIC_IPV6 \ - PUBLIC_IPV6 - - if [ ! $PUBLIC_IPV6_EXITCODE ]; then - # user hit ESC/cancel - exit - fi - fi -fi - -# Get the IP addresses of the local network interface(s) that are connected -# to the Internet. We need these when we want to have services bind only to -# the public network interfaces (not loopback, not tunnel interfaces). -if [ -z "$PRIVATE_IP" ]; then - PRIVATE_IP=$(get_default_privateip 4) -fi -if [ -z "$PRIVATE_IPV6" ]; then - PRIVATE_IPV6=$(get_default_privateip 6) -fi -if [[ -z "$PRIVATE_IP" && -z "$PRIVATE_IPV6" ]]; then - echo - echo "I could not determine the IP or IPv6 address of the network inteface" - echo "for connecting to the Internet. Setup must stop." - echo - hostname -I - route - echo - exit -fi - -# We need a country code to generate a certificate signing request. However -# if a CSR already exists then we won't be generating a new one and there's -# no reason to ask for the country code now. $STORAGE_ROOT has not yet been -# set so we'll check if $DEFAULT_STORAGE_ROOT and $DEFAULT_CSR_COUNTRY are -# set (the values from the current mailinabox.conf) and if the CSR exists -# in the expected location. -if [ ! -z "$DEFAULT_STORAGE_ROOT" ] && [ ! -z "$DEFAULT_CSR_COUNTRY" ] && [ -f $DEFAULT_STORAGE_ROOT/ssl/ssl_cert_sign_req.csr ]; then - CSR_COUNTRY=$DEFAULT_CSR_COUNTRY -fi - -if [ -z "$CSR_COUNTRY" ]; then - # Get a list of country codes. Separate codes from country names with a ^. - # The input_menu function modifies shell word expansion to ignore spaces - # (since country names can have spaces) and use ^ instead. - country_code_list=$(grep -v "^#" setup/csr_country_codes.tsv | sed "s/\(..\)\t\([^\t]*\).*/\1^\2/") - - input_menu "Country Code" \ - "Choose the country where you live or where your organization is based. - \n\n(This is used to create an SSL certificate.) - \n\nCountry Code:" \ - "$country_code_list" \ - CSR_COUNTRY - - if [ -z "$CSR_COUNTRY" ]; then - # user hit ESC/cancel - exit - fi -fi +# Ask the user for the PRIMARY_HOSTNAME, PUBLIC_IP, PUBLIC_IPV6, and CSR_COUNTRY +# if values have not already been set in environment variables. When running +# non-interactively, be sure to set values for all! +. setup/questions.sh # Automatic configuration, e.g. as used in our Vagrant configuration. if [ "$PUBLIC_IP" = "auto" ]; then @@ -311,63 +105,9 @@ curl -s -d POSTDATA --user $( Date: Mon, 25 Aug 2014 08:18:46 -0400 Subject: [PATCH 8/8] bootstrap.sh: allow overring the tag to checkout by setting the TAG environment variable (helpful for debugging) --- setup/bootstrap.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/setup/bootstrap.sh b/setup/bootstrap.sh index 21575ccb..dd8f2566 100755 --- a/setup/bootstrap.sh +++ b/setup/bootstrap.sh @@ -6,7 +6,9 @@ # ######################################################### -TAG=14.08-beta +if [ -z "$TAG" ]; then + TAG=14.08-beta +fi # Are we running as root? if [[ $EUID -ne 0 ]]; then @@ -27,7 +29,7 @@ if [ ! -d mailinabox ]; then # If it does exist, update it. else - echo Updating Mail-in-a-Box . . . + echo Updating Mail-in-a-Box to $TAG . . . cd mailinabox git fetch if ! git checkout -q $TAG; then