| #!/bin/bash |
| # |
| # For a more fool-proof gce-xfstests setup,,, |
| # |
| |
| XFSTESTS_FLAVOR=gce |
| if test -n "$GCE_XFSTESTS_DIR" |
| then |
| DIR="$GCE_XFSTESTS_DIR" |
| else |
| DIR="$(dirname "$(dirname "$0")")" |
| fi |
| if test ! -f "$DIR/util/get-config" |
| then |
| echo "$(basename "$0"): couldn't find $DIR/util/get-config" |
| exit 1 |
| fi |
| |
| . "$DIR/util/get-config" |
| |
| function gce_gen_cert() { |
| # Making an SSL cert for a project, storing it in GCS bucket. |
| |
| if [ -z "$REGEN_CERT" ] && \ |
| gsutil -q stat gs://$GS_BUCKET/gce-xfstests-cert.pem && \ |
| gsutil -q stat gs://$GS_BUCKET/gce-xfstests-server.pem && \ |
| gsutil -q stat gs://$GS_BUCKET/gce-xfstests-key.pem |
| then |
| return 0 |
| fi |
| |
| # generate self-signed cert. |
| |
| tmpdir=$(mktemp -d) |
| openssl req -x509 -newkey rsa:4096 -keyout "$tmpdir/gce-xfstests-key.pem" \ |
| -nodes -out "$tmpdir/gce-xfstests-cert.pem" -days 365 \ |
| -subj "/CN=*.$GCE_PROJECT.gce-xfstests" |
| |
| cat "$tmpdir/gce-xfstests-key.pem" "$tmpdir/gce-xfstests-cert.pem" \ |
| > "$tmpdir/gce-xfstests-server.pem" |
| |
| gsutil -m cp "$tmpdir/*" gs://$GS_BUCKET/ |
| rm -rf "$tmpdir" |
| } |
| |
| function gce_gen_ltm_pass() { |
| if gsutil -q stat gs://$GS_BUCKET/ltm-pass &>/dev/null |
| then |
| return 0 |
| fi |
| if ! type -P pwgen > /dev/null; then |
| echo 1>&2 "Please install pwgen, or upload a password to ltm-pass" |
| exit 1 |
| fi |
| pwgen -n -s 15 1 | gsutil cp - gs://$GS_BUCKET/ltm-pass |
| } |
| |
| if ! type gcloud >& /dev/null ; then |
| echo "You apparently do not have the Google Cloud SDK installed" |
| echo "Please visit https://cloud.google.com/sdk/docs/quickstart-linux" |
| echo "and follow the instructions there" |
| exit 1 |
| fi |
| |
| if test -z "$GS_BUCKET" -o -z "$GCE_PROJECT" -o -z "$GCE_ZONE" \ |
| -o -z "$GCE_KERNEL" |
| then |
| echo -e "Please make sure the following configuration variables are set in" |
| echo -e "~/.config/gce-xfstests or one of the other config files:" |
| echo -e "\tGS_BUCKET, GCE_PROJECT, GCE_ZONE, GCE_KERNEL\n" |
| echo -e "There are also more optional variables that can be set." |
| echo -e "Check Documentation/gce-xfstests.md for all options." |
| exit 1 |
| fi |
| |
| orig_account=$(run_gcloud auth list --filter status=ACTIVE --format="value(account)") |
| |
| : ${GCE_CONFIGURATION:=gce-xfstests} |
| if ! gcloud config configurations activate "${GCE_CONFIGURATION}" >& /dev/null ; then |
| gcloud config configurations create --activate "${GCE_CONFIGURATION}" |
| fi |
| account=$(gcloud auth list --filter status=ACTIVE --format="value(account)") |
| |
| if test -z "$account" ; then |
| if test -n "$orig_account"; then |
| gcloud config set account "$orig_account" |
| else |
| echo "No GCE credentials available. Please follow the" |
| echo "instructions to obtain the Google Cloud credentials" |
| echo "you wish to use for gce-xfstests" |
| gcloud config set core/project "$GCE_PROJECT" |
| if ! gcloud auth login --brief ; then |
| echo "Failed to get GCE credentials" |
| exit 1 |
| fi |
| fi |
| fi |
| |
| gcloud config set core/project "$GCE_PROJECT" |
| gcloud config set compute/zone "$GCE_ZONE" |
| |
| gcloud services enable compute.googleapis.com |
| gcloud services enable iam.googleapis.com |
| gcloud services enable cloudbuild.googleapis.com |
| gcloud services enable run.googleapis.com |
| gcloud services enable file.googleapis.com |
| |
| run_gcloud compute project-info add-metadata \ |
| --metadata=enable-guest-attributes=TRUE |
| |
| function SetupRole () { |
| local role="$1" |
| |
| if ! run_gcloud iam roles describe "for$role" >& /dev/null ; then |
| run_gcloud iam roles create "for$role" |
| else |
| run_gcloud iam roles undelete "for$role" >& /dev/null |
| fi |
| |
| if ! run_gcloud iam roles update "for$role" --file "$DIR/roles-$role.yaml" \ |
| --quiet >& /dev/null ; then |
| echo "Failed to update role for$role!" |
| # Re-run to get error message |
| run_gcloud iam roles update "for$role" --file "$DIR/roles-$role.yaml" \ |
| --quiet |
| exit 1 |
| fi |
| } |
| |
| function SetupServiceAccount () { |
| local srv_acct="$1" |
| local role="$2" |
| local name="$3" |
| local desc="$4" |
| |
| case "$role" in |
| */*) ;; |
| *) role="projects/$GCE_PROJECT/roles/$role" ;; |
| esac |
| |
| if ! run_gcloud iam service-accounts describe "$srv_acct" >& /dev/null ; then |
| run_gcloud iam service-accounts create "$name" \ |
| --description "$desc Service Account" \ |
| --display-name "$name" |
| if ! run_gcloud projects add-iam-policy-binding "$GCE_PROJECT" \ |
| --member "serviceAccount:$srv_acct" \ |
| --role "$role" \ |
| --verbosity none >& /dev/null ; then |
| echo "Failed to add iam policy binding for role $role" |
| # Re-run to get error message |
| run_gcloud projects add-iam-policy-binding "$GCE_PROJECT" \ |
| --member "serviceAccount:$srv_acct" \ |
| --role "$role" |
| exit 1 |
| fi |
| fi |
| |
| # when uniform bucket-level access is enabled, acl does not work |
| if gsutil acl get gs://$GS_BUCKET &> /dev/null -eq 0; then |
| # set via acl |
| gsutil acl ch -u "${srv_acct}:W" gs://$GS_BUCKET |
| else |
| # set via iams |
| if ! gsutil iam ch "serviceAccount:${srv_acct}:legacyBucketWriter" \ |
| gs://$GS_BUCKET &> /dev/null; then |
| echo "Error setting up gs://$GS_BUCKET write permissions for ${srv_acct}" |
| fi |
| fi |
| } |
| |
| function SetupServiceAccountCloudBuild () { |
| local GCE_PROJECT_NUMBER=`gcloud projects describe $GCE_PROJECT | grep projectNumber | cut -d ":" -f2 | xargs` |
| local ac_cloudbuild="serviceAccount:${GCE_PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" |
| |
| if ! run_gcloud projects add-iam-policy-binding $GCE_PROJECT \ |
| --member="$ac_cloudbuild" --role roles/run.viewer >& /dev/null ; then |
| # Re-run to get error message |
| run_gcloud projects add-iam-policy-binding $GCE_PROJECT \ |
| --member="$ac_cloudbuild" --role roles/run.viewer |
| exit 1 |
| fi |
| } |
| |
| get_cache_dir |
| rm -f "$GCE_CACHE_DIR/service-accounts-opts.$GCE_PROJECT" |
| |
| SetupRole TestVM |
| SetupRole LTMKCS |
| SetupRole ImgCreate |
| SetupRole Dashboard |
| |
| SetupServiceAccount "$SERVICE_ACCOUNT_VM" "forTestVM" "test-vm" "Test VM" |
| SetupServiceAccount "$SERVICE_ACCOUNT_LTM" "forLTMKCS" "ltm-kcs" "LTM/KCS" |
| SetupServiceAccount "$SERVICE_ACCOUNT_IMG" "forImgCreate" "img-create" \ |
| "Image Creation" |
| SetupServiceAccount "$SERVICE_ACCOUNT_DASH" "forDashboard" "dashboard" \ |
| "GCE xfstests dashboard" |
| SetupServiceAccountCloudBuild |
| |
| if ! run_gcloud_prj projects describe "$GCE_PROJECT" > /dev/null ; then |
| echo -e "Invalid GCE project: $GCE_PROJECT\n" |
| bad_config=yes |
| fi |
| |
| if ! gsutil ls -b "gs://$GS_BUCKET" > /dev/null ; then |
| echo -e "Invalid Cloud Storage Bucket: $GS_BUCKET\n" |
| bad_config=yes |
| fi |
| |
| if ! gcloud compute zones describe "$GCE_ZONE" > /dev/null ; then |
| echo -e "Invalid GCE zone: $GCE_ZONE\n" |
| bad_config=yes |
| fi |
| |
| if test -n "$GCE_MIN_SCR_SIZE" && \ |
| ( [[ ! "$GCE_MIN_SCR_SIZE" =~ ^[0-9]*$ ]] || \ |
| (( GCE_MIN_SCR_SIZE > 250 )) ); then |
| echo -e "Invalid minimum scratch size: $GCE_MIN_SCR_SIZE\n" |
| echo -e "Must be a number between 0 and 250 inclusive" |
| bad_config=yes |
| fi |
| |
| if test -n "$GCE_IMAGE_PROJECT" ; then |
| project="$GCE_IMAGE_PROJECT" |
| else |
| project=xfstests-cloud |
| fi |
| |
| if ! run_gcloud_prj compute images describe-from-family --project $project \ |
| xfstests > /dev/null ; then |
| if test -n "$GCE_IMAGE_PROJECT" ; then |
| echo "Bad image project: $GCE_IMAGE_PROJECT" |
| else |
| echo "You need to add yourself to the gce-xfstests Googlegroup" |
| echo -e "Please visit:\n" |
| echo -e '\thttps://groups.google.com/forum/#!forum/gce-xfstests\n' |
| fi |
| bad_config=1 |
| fi |
| |
| if test -n "$bad_config"; then |
| exit 1 |
| fi |
| |
| addr= |
| if test -n "$GCE_REPORT_EMAIL" -o -n "$GCE_REPORT_FAIL_EMAIL"; then |
| if test -z "$GCE_SG_API" ; then |
| echo "Missing Sendgrid API key; you need to set GCE_SG_API" |
| fi |
| if test -n "$GCE_REPORT_SENDER" ; then |
| addr="$GCE_REPORT_SENDER" |
| elif test -n "$GCE_REPORT_EMAIL" ; then |
| # take first email in the comma separated list |
| addr="${GCE_REPORT_EMAIL%,*}" |
| else |
| # this is needed to support the case where we only |
| # want emails sent upon failure |
| addr="${GCE_REPORT_FAIL_EMAIL%,*}" |
| fi |
| addr=$(echo $addr | sed -e 's/.*@//') |
| spf=$(dig -t txt +short "$addr" | grep v=spf1) |
| if test -n "$spf" && ! echo "$spf" | grep -q "include:sendgrid.net" ; then |
| echo "Warning: the spf record for the domain $addr does not" |
| echo "mention sendgrid.net:" |
| echo -e "\n\t$spf\n" |
| echo -e "If you can not change the SPF record for $addr," |
| echo -e "you should consider configuring a different sender" |
| echo -e "via the GCE_REPORT_SENDER configuration variable.\n" |
| echo -e "If you can change the SPF record, please add" |
| echo -e "'include:sendgrid.net' before the 'all' mechanism" |
| echo -e "in the spf record for $addr. Otherwise, mail sent to" |
| echo -e "'$GCE_REPORT_EMAIL $GCE_REPORT_FAIL_EMAIL' from" |
| echo -e "'$GCE_REPORT_SENDER' may be rejected as spam.\n" |
| fi |
| fi |
| |
| for rule in "${GCE_FIREWALL_RULES[@]}"; do |
| rule_name=$(echo $rule | cut -d' ' -f1) |
| if test -z "$(run_gcloud compute firewall-rules list $rule_name | sed -e 1d)" |
| then |
| echo "Creating $rule_name firewall rule..." |
| run_gcloud compute firewall-rules create $rule |
| fi |
| done |
| unset rule rule_name |
| |
| if [ "$1" == "--regenerate-ssl-cert" ] |
| then |
| echo "Regenerating certificate." |
| REGEN_OPTS="--force-regen" |
| fi |
| |
| $DIR/util/gce-setup-cert $REGEN_OPTS |
| gce_gen_ltm_pass |
| |
| exit 0 |