├── nginx
├── ok
├── .gitignore
├── Dockerfile
├── app.yaml
├── install.sh
└── nginx.conf.template
├── .gitignore
├── CHANGELOG.md
├── .gitmodules
├── ssh
├── vm
├── configure_pygments.sh
├── sites
│ └── phabricator.conf
├── configure_php.sh
├── configure_mailgun.sh
├── configure_submodules.sh
├── configure_users.sh
├── configure_notifications.sh
├── configure_phabricator.sh
├── configure_gcloud.sh
├── configure_hosted_repos.sh
├── configure_apache.sh
├── upgrade.sh
├── configure_ssh.sh
├── configure_sendgrid.sh
├── startup.sh
├── configure_sql.sh
└── install.sh
├── sync_to_latest
├── upgrade
├── phabricator.sh.template
├── CONTRIBUTING.md
├── README.md
├── lib
└── init.sh
├── LICENSE
└── install
/nginx/ok:
--------------------------------------------------------------------------------
1 | ok
2 |
--------------------------------------------------------------------------------
/nginx/.gitignore:
--------------------------------------------------------------------------------
1 | nginx.conf
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /config
2 | /transaction.yaml
3 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 1.0.0
2 |
3 | * Initial release.
4 |
--------------------------------------------------------------------------------
/nginx/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM nginx:latest
2 | COPY nginx.conf /etc/nginx/nginx.conf
3 | COPY ok /usr/share/nginx/www/_ah/start
4 | COPY ok /usr/share/nginx/www/_ah/health
5 | RUN chmod -R a+rx /usr/share/nginx/www
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "vm/third_party/phabricator"]
2 | path = vm/third_party/phabricator
3 | url = https://github.com/phacility/phabricator.git
4 | [submodule "vm/third_party/arcanist"]
5 | path = vm/third_party/arcanist
6 | url = https://github.com/phacility/arcanist.git
7 | [submodule "vm/third_party/libphutil"]
8 | path = vm/third_party/libphutil
9 | url = https://github.com/phacility/libphutil.git
10 |
--------------------------------------------------------------------------------
/nginx/app.yaml:
--------------------------------------------------------------------------------
1 | runtime: custom
2 | vm: true
3 | api_version: 1
4 | threadsafe: yes
5 |
6 | automatic_scaling:
7 | min_num_instances: 2
8 |
9 | builtins:
10 | - appstats: on
11 |
12 | network:
13 | name: phabricator
14 |
15 | handlers:
16 | - url: /favicon.ico
17 | static_files: favicon.ico
18 | upload: favicon.ico
19 |
20 | - url: /api/.*
21 | script: dynamic
22 |
23 | - url: /res/.*
24 | script: dynamic
25 |
26 | - url: /file/data/.*
27 | script: dynamic
28 |
29 | - url: /ws/.*
30 | script: dynamic
31 |
32 | - url: /auth/register/
33 | script: dynamic
34 |
35 | - url: /.*
36 | script: dynamic
37 |
--------------------------------------------------------------------------------
/nginx/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | . ../lib/init.sh
18 |
19 | gcloud_appengine deploy --version=1 --promote app.yaml
20 |
--------------------------------------------------------------------------------
/ssh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | . lib/init.sh
18 |
19 | open_ssh
20 | gcloud --project=${PROJECT} compute ssh $VM_NAME --zone=$ZONE --ssh-flag="-p $PORT"
21 |
--------------------------------------------------------------------------------
/vm/configure_pygments.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | # Install pip
20 | sudo apt-get install -y python-pip
21 |
22 | # Install pygments
23 | sudo pip install Pygments
24 |
--------------------------------------------------------------------------------
/sync_to_latest:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | . lib/init.sh
18 |
19 | # Terminate execution on command failure
20 | set -e
21 |
22 | git submodule foreach "git fetch;git checkout origin/stable"
23 |
--------------------------------------------------------------------------------
/vm/sites/phabricator.conf:
--------------------------------------------------------------------------------
1 |
2 | DocumentRoot /opt/phabricator/webroot
3 | SetEnvIf Request_URI "^/_ah/stop" shutdown
4 | CustomLog /usr/local/apache/logs/shutdown.log common env=shutdown
5 | CustomLog /var/log/phabricator/access.log combined
6 | ErrorLog /var/log/phabricator/apache_phabricator_err.log
7 |
8 | RewriteEngine on
9 | RewriteRule ^/_ah/health - [L,QSA]
10 | RewriteRule ^/_ah/stop - [L,QSA]
11 | RewriteRule ^/rsrc/(.*) - [L,QSA]
12 | RewriteRule ^/favicon.ico - [L,QSA]
13 | RewriteRule ^(.*)$ /index.php?__path__=$1 [B,L,QSA]
14 |
15 | # Tell Apache to allow user access to documents under
16 | # Phabricator's webroot directory.
17 |
18 | Require all granted
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/upgrade:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | . lib/init.sh
18 |
19 | # Terminate execution on command failure
20 | set -e
21 |
22 | echo "About to connect via ssh to upgrade your cluster. Press enter to continue."
23 | read
24 |
25 | open_ssh
26 |
27 | remote_exec "if [ ! -d phabricator ]; then git clone $GITHUB_REPO; else cd phabricator; git fetch; git rebase origin/master; fi" || exit 1
28 | remote_exec "cd /opt;bash ~/phabricator/vm/upgrade.sh" || exit 1
29 |
--------------------------------------------------------------------------------
/vm/configure_php.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | function disable_php {
20 | if [ $(grep -c "^$1" /etc/php5/apache2/php.ini) = 0 ]; then
21 | echo "Disabling $1..."
22 | echo "$1 = 0" | sudo tee --append /etc/php5/apache2/php.ini
23 | fi
24 | }
25 |
26 | disable_php apc.stat
27 | disable_php apc.slam_defense
28 | disable_php opcache.validate_timestamps
29 |
30 | if [ $(grep -c "^post_max_size = 8M$" /etc/php5/apache2/php.ini) -ne 0 ]; then
31 | echo "Increasing post max size to 32M.";
32 | sudo sed -i -e "s/post_max_size = 8M/post_max_size = 32M/" /etc/php5/apache2/php.ini
33 | fi
34 |
35 |
--------------------------------------------------------------------------------
/phabricator.sh.template:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | ZONE= # Must provide a zone. Run `gcloud compute zones list` for a list.
18 |
19 | # Recommended. Provide if you are using Mailgun to send mail.
20 | MAILGUN_APIKEY=
21 | MAILGUN_SMTP_DOMAIN_KEY_TXT=
22 |
23 | # Recommended. Provide if you intend to serve phabricator behind a custom domain.
24 | CUSTOM_DOMAIN=
25 | CUSTOM_DOMAIN_A_RECORD=
26 | CUSTOM_DOMAIN_AAAA_RECORD=
27 |
28 | # Only applies when CUSTOM_DOMAIN is provided.
29 | NOTIFICATIONS_SUBDOMAIN=n
30 | GIT_SUBDOMAIN=git
31 |
32 | # Only modify these if installing phabricator into an existing cluster.
33 | NETWORK_NAME=phabricator
34 | DNS_NAME=phabricator
35 | SQL_NAME=phabricator
36 | ADDRESS_NAME=phabricator
37 | VM_NAME=phabricator
38 |
--------------------------------------------------------------------------------
/vm/configure_mailgun.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | if [ "$#" -lt 2 ]; then
20 | echo "Usage: ${BASH_SOURCE[0]} "
21 | exit 1
22 | fi
23 |
24 | PHABRICATOR_BASE_DOMAIN=$1
25 | MAILGUN_APIKEY=$2
26 |
27 | pushd phabricator >> /dev/null
28 |
29 | echo "Configuring Phabricator for Mailgun..."
30 |
31 | sudo ./bin/config set mailgun.api-key $MAILGUN_APIKEY
32 | sudo ./bin/config set mailgun.domain $PHABRICATOR_BASE_DOMAIN
33 |
34 | sudo ./bin/config set --database metamta.mail-adapter PhabricatorMailImplementationMailgunAdapter
35 | sudo ./bin/config set --database metamta.domain $PHABRICATOR_BASE_DOMAIN
36 | sudo ./bin/config set --database metamta.default-address noreply@$PHABRICATOR_BASE_DOMAIN
37 |
38 | popd >> /dev/null
39 |
--------------------------------------------------------------------------------
/vm/configure_submodules.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
20 |
21 | pushd $DIR >> /dev/null
22 | git submodule update --init --recursive
23 | popd >> /dev/null
24 |
25 | function clone {
26 | if [ ! -d $1 ]; then
27 | echo "Cloning $1..."
28 | sudo git clone $DIR/third_party/$1 $1 || exit 1
29 | else
30 | pushd $1 >> /dev/null
31 | sudo git fetch $DIR/third_party/$1
32 | popd >> /dev/null
33 | fi
34 |
35 | pushd $DIR >> /dev/null
36 | sha=$(git submodule status third_party/$1 | cut -d' ' -f2)
37 | popd >> /dev/null
38 | pushd $1 >> /dev/null
39 | echo "Checking out $1/$sha..."
40 | sudo git checkout -q $sha
41 | popd >> /dev/null
42 | }
43 |
44 | clone arcanist
45 | clone libphutil
46 | clone phabricator
47 |
--------------------------------------------------------------------------------
/nginx/nginx.conf.template:
--------------------------------------------------------------------------------
1 | events {
2 | worker_connections 768;
3 | }
4 |
5 | http {
6 | sendfile on;
7 | tcp_nopush on;
8 | tcp_nodelay on;
9 | keepalive_timeout 65;
10 | types_hash_max_size 2048;
11 | include /etc/nginx/mime.types;
12 | default_type application/octet-stream;
13 | client_max_body_size 100M;
14 |
15 | access_log /var/log/app_engine/app.log;
16 | error_log /var/log/app_engine/app.log;
17 |
18 | gzip on;
19 | gzip_disable "msie6";
20 |
21 | server {
22 | listen 8080;
23 | server_name $PHABRICATOR_URL;
24 | location / {
25 | proxy_pass http://$PHABRICATOR_IP:8080;
26 | proxy_set_header Host $host;
27 | proxy_set_header X-Real-IP $remote_addr;
28 | proxy_set_header X-Forwarded-for $remote_addr;
29 | port_in_redirect off;
30 | proxy_connect_timeout 300;
31 | }
32 | location /_ah {
33 | root /usr/share/nginx/www;
34 | }
35 | }
36 |
37 | server {
38 | listen 8080;
39 | server_name $PHABRICATOR_ALTERNATE_URL;
40 | location / {
41 | proxy_pass http://$PHABRICATOR_IP:8080;
42 | proxy_set_header Host $host;
43 | proxy_set_header X-Real-IP $remote_addr;
44 | proxy_set_header X-Forwarded-for $remote_addr;
45 | port_in_redirect off;
46 | proxy_connect_timeout 300;
47 | }
48 | location /_ah {
49 | root /usr/share/nginx/www;
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/vm/configure_users.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | if ! cat /etc/passwd | grep "^phabricator-daemon" >> /dev/null; then
20 | sudo useradd -r -s /bin/bash phabricator-daemon
21 | fi
22 |
23 | if ! cat /etc/passwd | grep "^git" >> /dev/null; then
24 | sudo useradd -r -s /bin/bash git
25 | fi
26 |
27 | if ! cat /etc/passwd | grep "^aphlict" >> /dev/null; then
28 | sudo useradd -r -s /bin/bash aphlict
29 | fi
30 |
31 | if sudo cat /etc/shadow | grep "^git:\!:" >> /dev/null; then
32 | sudo sed -i -e "s/^git:\!:/git:NP:/" /etc/shadow
33 | fi
34 |
35 | if ! sudo cat /etc/sudoers | grep "^git ALL=(phabricator-daemon)" >> /dev/null; then
36 | echo "git ALL=(phabricator-daemon) SETENV: NOPASSWD: $(whereis -b git-upload-pack | cut -d' ' -f2-), $(whereis -b git-receive-pack | cut -d' ' -f2-)" | (sudo su -c 'EDITOR="tee -a" visudo')
37 | fi
38 |
--------------------------------------------------------------------------------
/vm/configure_notifications.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | if [ "$#" -lt 1 ]; then
20 | echo "Usage: ${BASH_SOURCE[0]} "
21 | exit 1
22 | fi
23 |
24 | NOTIFICATIONS_URL=$1
25 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
26 |
27 | sudo apt-get install -y npm
28 |
29 | ln -s /usr/bin/nodejs /usr/bin/node
30 |
31 | pushd phabricator/support/aphlict/server >> /dev/null
32 | sudo npm install ws
33 | popd >> /dev/null
34 |
35 | # Start the notification server
36 | pushd phabricator >> /dev/null
37 |
38 | sudo ./bin/config set notification.servers '[{"type":"client","host":"'$NOTIFICATIONS_URL'","port":22280,"protocol":"http"},{"type":"admin","host":"127.0.0.1","port":22281,"protocol":"http"}]'
39 |
40 | sudo touch /var/log/aphlict.log
41 | sudo chmod a+w /var/log/aphlict.log
42 | sudo chown -R aphlict:aphlict /var/tmp/aphlict/
43 |
44 | popd >> /dev/null
45 |
--------------------------------------------------------------------------------
/vm/configure_phabricator.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
20 |
21 | pushd phabricator >> /dev/null
22 |
23 | echo "Stopping daemons..."
24 |
25 | sudo ./bin/phd stop
26 |
27 | sudo chown -R phabricator-daemon /var/tmp/phd
28 |
29 | sudo ./bin/config set phabricator.timezone America/Los_Angeles
30 | sudo ./bin/config set phabricator.show-prototypes true
31 | sudo ./bin/config set pygments.enabled true
32 | sudo ./bin/config set config.ignore-issues '{"mysql.ft_boolean_syntax":true, "mysql.ft_stopword_file": true, "daemons.need-restarting": true, "mysql.max_allowed_packet": true, "large-files": true, "mysql.innodb_buffer_pool_size": true}'
33 | sudo ./bin/config set environment.append-paths '["/usr/lib/git-core/"]'
34 | sudo ./bin/config set phd.user phabricator-daemon
35 | sudo ./bin/config set diffusion.ssh-user git
36 |
37 | popd >> /dev/null
38 |
--------------------------------------------------------------------------------
/vm/configure_gcloud.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
20 |
21 | # Install unzip
22 | sudo apt-get install -y unzip
23 |
24 | # Remove any existing zip first
25 | sudo rm -f google-cloud-sdk.zip
26 |
27 | # Download google-cloud_sdk
28 | sudo wget https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.zip
29 |
30 | # Unzip sdk into google directory
31 | sudo unzip -uo google-cloud-sdk.zip -d /google/
32 |
33 | sudo rm -f google-cloud-sdk.zip
34 |
35 | if [ $(grep -c "\/google\/google-cloud-sdk\/bin" /etc/profile) -eq 0 ]; then
36 | echo "Adding google cloud SDK to path...";
37 | echo PATH=/google/google-cloud-sdk/bin:\$PATH | sudo tee --append /etc/profile
38 | fi
39 |
40 | sudo /google/google-cloud-sdk/install.sh \
41 | --rc-path=/etc/bash.bashrc \
42 | --usage-reporting=false \
43 | --command-completion=true \
44 | --path-update=true
45 |
46 | sudo /google/google-cloud-sdk/bin/gcloud config set --installation component_manager/disable_update_check True
47 |
--------------------------------------------------------------------------------
/vm/configure_hosted_repos.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | if [ ! -d /mnt/git-repos ]; then
20 | echo "Creating hosted repo folder..."
21 | sudo mkdir -p /mnt/git-repos
22 |
23 | # TODO: This is assuming that the "first" disk mounted is the git-repos one and that its name is
24 | # /dev/sdb. We should be identifying the disk name from an `instances describe` call.
25 | sudo /usr/share/google/safe_format_and_mount -m "mkfs.ext4 -F" /dev/sdb /mnt/git-repos
26 |
27 | sudo chown phabricator-daemon:phabricator-daemon /mnt/git-repos
28 | fi
29 |
30 | if [ ! -d /mnt/file-storage ]; then
31 | echo "Creating file storage folder..."
32 | sudo mkdir -p /mnt/file-storage
33 |
34 | # TODO: This is assuming that the "second" disk mounted is the git-repos one and that its name is
35 | # /dev/sdc. We should be identifying the disk name from an `instances describe` call.
36 | sudo /usr/share/google/safe_format_and_mount -m "mkfs.ext4 -F" /dev/sdc /mnt/file-storage
37 |
38 | sudo chown www-data:www-data /mnt/file-storage
39 | fi
40 |
41 | pushd phabricator >> /dev/null
42 |
43 | sudo ./bin/config set repository.default-local-path /mnt/git-repos
44 | sudo ./bin/config set storage.local-disk.path /mnt/file-storage
45 |
46 | popd >> /dev/null
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Want to contribute? Great! First, read this page (including the small print at the end).
2 |
3 | ## Pull requests
4 |
5 | Pull requests can be hard to review if they try to tackle too many things
6 | at once. Phabricator's "[Writing Reviewable Code](https://secure.phabricator.com/book/phabflavor/article/writing_reviewable_code/)"
7 | provides a set of guidelines that help increase the likelihood of your
8 | pull request getting merged.
9 |
10 | In short (slightly modified from the original article):
11 |
12 | - A pull request should be as small as possible, but no smaller.
13 | - The smallest a pull request can be is a single cohesive idea: don't
14 | make pull requests so small that they are meaningless on their own.
15 | - Turn large pull requests into small pull requests by dividing large
16 | problems into smaller problems and solving the small problems one at
17 | a time.
18 | - Write sensible pull request descriptions.
19 |
20 | ### Before you contribute
21 |
22 | Before we can use your code, you must sign the
23 | [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1)
24 | (CLA), which you can do online. The CLA is necessary mainly because you own the
25 | copyright to your changes, even after your contribution becomes part of our
26 | codebase, so we need your permission to use and distribute your code. We also
27 | need to be sure of various other things—for instance that you'll tell us if you
28 | know that your code infringes on other people's patents. You don't have to sign
29 | the CLA until after you've submitted your code for review and a member has
30 | approved it, but you must do it before we can put your code into our codebase.
31 | Before you start working on a larger contribution, you should get in touch with
32 | us first through the issue tracker with your idea so that we can help out and
33 | possibly guide you. Coordinating up front makes it much easier to avoid
34 | frustration later on.
35 |
36 | ### The small print
37 |
38 | Contributions made by corporations are covered by a different agreement than
39 | the one above, the [Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate).
40 |
--------------------------------------------------------------------------------
/vm/configure_apache.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
20 |
21 | function safe_copy {
22 | if [ ! -f $2 ]; then
23 | echo "Copying $1..."
24 | sudo cp $1 $2
25 | else
26 | if ! cmp --silent $1 $2; then
27 | echo "Overwrite existing $1 at $2?"
28 | select yn in "Yes" "No"; do
29 | case $yn in
30 | Yes ) echo "Updating $2 site...";sudo cp $1 $2; break;;
31 | No ) exit;;
32 | esac
33 | done
34 | fi
35 | fi
36 | }
37 |
38 | if [ $(grep -c "^Listen 80$" /etc/apache2/ports.conf) -ne 0 ]; then
39 | echo "Listening port set to 8080.";
40 | sudo sed -i -e 's/^Listen 80$/Listen 8080/' /etc/apache2/ports.conf
41 | fi
42 |
43 | if [ -f /etc/apache2/sites-enabled/000-default.conf ]; then
44 | echo "Removing default site..."
45 | sudo rm -f /etc/apache2/sites-enabled/000-default.conf
46 | fi
47 |
48 | safe_copy $DIR/sites/phabricator.conf /etc/apache2/sites-available/phabricator.conf
49 |
50 | if [ ! -h /etc/apache2/sites-enabled/phabricator.conf ]; then
51 | echo "Activating phabricator site..."
52 | sudo ln -s /etc/apache2/sites-available/phabricator.conf /etc/apache2/sites-enabled/phabricator.conf
53 | fi
54 |
55 | if [ ! -d /usr/local/apache/logs ]; then
56 | echo "Configuring apache logs..."
57 | sudo mkdir -p /usr/local/apache/logs && sudo chown www-data:www-data /usr/local/apache/logs
58 | fi
59 |
60 | if [ ! -d /var/log/phabricator ]; then
61 | echo "Configuring phabricator logs..."
62 | sudo mkdir -p /var/log/phabricator && sudo chown www-data:www-data /var/log/phabricator
63 | fi
64 |
65 |
--------------------------------------------------------------------------------
/vm/upgrade.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
18 |
19 | set -e
20 |
21 | # NOTE: This script assumes you are running it from a directory which contains
22 | # arcanist/, libphutil/, and phabricator/.
23 |
24 | pushd $DIR >> /dev/null
25 |
26 | sudo git fetch
27 | sudo git rebase origin/master
28 | sudo git submodule update
29 |
30 | popd >> /dev/null
31 |
32 | ### CYCLE WEB SERVER AND DAEMONS ###############################################
33 |
34 | pushd phabricator >> /dev/null
35 |
36 | # Stop daemons.
37 | sudo su phabricator-daemon -c "./bin/phd stop"
38 |
39 | # If running the notification server, stop it.
40 | sudo su aphlict -c "./bin/aphlict stop"
41 |
42 | # Stop the webserver.
43 | sudo apachectl stop
44 |
45 | ### UPDATE SYSTEM PACKAGES ######################################################
46 |
47 | sudo apt-get -qq update
48 | sudo apt-get upgrade -y
49 | sudo apt-get autoremove -y
50 |
51 | # apt-get may have updated apache; ensure that it's truly stopped.
52 | sudo apachectl stop
53 |
54 | ### UPDATE WORKING COPIES ######################################################
55 |
56 | popd >> /dev/null
57 |
58 | sudo $DIR/configure_submodules.sh
59 |
60 | pushd phabricator >> /dev/null
61 |
62 | # Upgrade the database schema.
63 | sudo ./bin/storage upgrade --force
64 |
65 | # Restart the webserver.
66 | sudo apachectl start
67 |
68 | # Restart daemons.
69 | sudo su phabricator-daemon -c "./bin/phd start"
70 |
71 | # If running the notification server, start it.
72 | if hash nodejs 2>/dev/null; then
73 | sudo su aphlict -c "./bin/aphlict start"
74 | fi
75 |
76 | popd >> /dev/null
77 |
--------------------------------------------------------------------------------
/vm/configure_ssh.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | if [ "$#" -lt 1 ]; then
20 | echo "Usage: ${BASH_SOURCE[0]} "
21 | exit 1
22 | fi
23 |
24 | GIT_URL=$1
25 |
26 | if [ $(grep -c "^Port 22$" /etc/ssh/sshd_config) -ne 0 ]; then
27 | echo "Listening port set to 222.";
28 | sudo sed -i -e 's/^Port 22$/Port 222/' /etc/ssh/sshd_config
29 |
30 | sudo service ssh restart
31 | fi
32 |
33 | sudo mkdir -p /etc/libexec/
34 |
35 | if [ ! -f /etc/libexec/phabricator-ssh-hook.sh ]; then
36 | sudo cp phabricator/resources/sshd/phabricator-ssh-hook.sh /etc/libexec/
37 | fi
38 |
39 | sudo sed -i -e "s/^VCSUSER=.*$/VCSUSER=\"git\"/" /etc/libexec/phabricator-ssh-hook.sh
40 | sudo sed -i -e 's:^ROOT=.*$:ROOT="'$(pwd)'/phabricator":' /etc/libexec/phabricator-ssh-hook.sh
41 | sudo chown root /etc/libexec/phabricator-ssh-hook.sh
42 | sudo chmod 755 /etc/libexec/phabricator-ssh-hook.sh
43 |
44 | if [ ! -f /etc/ssh/sshd_config.phabricator ]; then
45 | sudo cp phabricator/resources/sshd/sshd_config.phabricator.example /etc/ssh/sshd_config.phabricator
46 | fi
47 |
48 | sudo sed -i -e "s:^AuthorizedKeysCommand .*$:AuthorizedKeysCommand /etc/libexec/phabricator-ssh-hook.sh:" /etc/ssh/sshd_config.phabricator
49 | sudo sed -i -e "s:^AuthorizedKeysCommandUser .*$:AuthorizedKeysCommandUser git:" /etc/ssh/sshd_config.phabricator
50 | sudo sed -i -e "s:^AllowUsers .*$:AllowUsers git:" /etc/ssh/sshd_config.phabricator
51 |
52 | # TODO: Turn this into a service.
53 | sudo $(whereis -b sshd | cut -d' ' -f2) -f /etc/ssh/sshd_config.phabricator
54 |
55 | pushd phabricator >> /dev/null
56 | sudo ./bin/config set diffusion.ssh-host $GIT_URL
57 | popd >> /dev/null
58 |
--------------------------------------------------------------------------------
/vm/configure_sendgrid.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | sudo apt-get install postfix libsasl2-modules -y
20 |
21 | if [ $(grep -c "^default_transport" /etc/postfix/main.cf) -ne 0 ]; then
22 | echo "Disabling default_transport...";
23 | sed -i -e "s/^default_transport/# default_transport/" /etc/postfix/main.cf
24 | fi
25 |
26 | if [ $(grep -c "^relay_transport" /etc/postfix/main.cf) -ne 0 ]; then
27 | echo "Disabling relay_transport...";
28 | sed -i -e "s/^relay_transport/# relay_transport/" /etc/postfix/main.cf
29 | fi
30 |
31 | if [ $(grep -c "^relayhost" /etc/postfix/main.cf) -eq 0 ]; then
32 | echo "Adding relayhost...";
33 | echo "relayhost = [smtp.sendgrid.net]:2525" >> /etc/postfix/main.cf
34 | else
35 | echo "Editing relayhost...";
36 | sed -i -e "s/^relayhost.+$/#relayhost = [smtp.sendgrid.net]:2525/" /etc/postfix/main.cf
37 | fi
38 |
39 | if [ $(grep -c "^smtp_tls_security_level" /etc/postfix/main.cf) -eq 0 ]; then
40 | echo "Adding smtp_tls_security_level...";
41 | echo "smtp_tls_security_level = encrypt" >> /etc/postfix/main.cf
42 | echo "smtp_sasl_auth_enable = yes" >> /etc/postfix/main.cf
43 | echo "smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd" >> /etc/postfix/main.cf
44 | echo "header_size_limit = 4096000" >> /etc/postfix/main.cf
45 | echo "smtp_sasl_security_options = noanonymous" >> /etc/postfix/main.cf
46 | fi
47 |
48 | if [ ! -f /etc/postfix/sasl_passwd.db ]; then
49 | echo "Please enter your sendmail credentials from https://app.sendgrid.com/settings/credentials"
50 | echo -n "Sendgrid Username: "
51 | read username
52 | echo
53 | echo -n "Sendgrid Password: "
54 | read -s password
55 | echo
56 |
57 | echo "[smtp.sendgrid.net]:2525 $username:$password" >> /etc/postfix/sasl_passwd
58 | postmap /etc/postfix/sasl_passwd
59 | rm /etc/postfix/sasl_passwd
60 | chmod 600 /etc/postfix/sasl_passwd.db
61 | fi
62 |
63 | echo "Restarting postfix..."
64 | /etc/init.d/postfix restart
65 |
--------------------------------------------------------------------------------
/vm/startup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | #VM_NAME=
18 | #DNS_NAME=
19 | #TOP_LEVEL_DOMAIN=
20 | #GIT_SUBDOMAIN=
21 | #NOTIFICATIONS_SUBDOMAIN=
22 |
23 | gcloud_instances() {
24 | sudo /google/google-cloud-sdk/bin/gcloud --quiet compute instances "$@"
25 | }
26 |
27 | VM_EXTERNAL_IP=$(gcloud_instances list | grep "\b$VM_NAME\b" | awk '{print $5}')
28 |
29 | pushd /opt/phabricator >> /dev/null
30 |
31 | sudo su phabricator-daemon -c "./bin/phd restart"
32 | sudo su aphlict -c "./bin/aphlict restart"
33 | sudo $(whereis -b sshd | cut -d' ' -f2) -f /etc/ssh/sshd_config.phabricator
34 |
35 | gcloud_dns_records() {
36 | sudo /google/google-cloud-sdk/bin/gcloud --quiet dns record-sets "$@" --zone="$DNS_NAME"
37 | }
38 |
39 | if [[ -n "$GIT_SUBDOMAIN" || -n "$NOTIFICATIONS_SUBDOMAIN" ]]; then
40 | if gcloud_dns_records transaction describe >> /dev/null 2>&1; then
41 | gcloud_dns_records transaction abort
42 | fi
43 |
44 | gcloud_dns_records transaction start
45 | if [ -n "$GIT_SUBDOMAIN" ]; then
46 | existing=$(gcloud_dns_records list | grep "$GIT_SUBDOMAIN.$TOP_LEVEL_DOMAIN." | grep "\bA\b" | awk '{print $4}')
47 | if [ -n "$existing" ]; then
48 | gcloud_dns_records transaction remove --name="$GIT_SUBDOMAIN.$TOP_LEVEL_DOMAIN." --ttl=60 --type=A "$existing"
49 | fi
50 | gcloud_dns_records transaction add --name="$GIT_SUBDOMAIN.$TOP_LEVEL_DOMAIN." --ttl=60 --type=A $VM_EXTERNAL_IP
51 | fi
52 | if [ -n "$NOTIFICATIONS_SUBDOMAIN" ]; then
53 | existing=$(gcloud_dns_records list | grep "$NOTIFICATIONS_SUBDOMAIN.$TOP_LEVEL_DOMAIN." | grep "\bA\b" | awk '{print $4}')
54 | if [ -n "$existing" ]; then
55 | gcloud_dns_records transaction remove --name="$NOTIFICATIONS_SUBDOMAIN.$TOP_LEVEL_DOMAIN." --ttl=60 --type=A "$existing"
56 | fi
57 | gcloud_dns_records transaction add --name="$NOTIFICATIONS_SUBDOMAIN.$TOP_LEVEL_DOMAIN." --ttl=60 --type=A $VM_EXTERNAL_IP
58 | fi
59 | gcloud_dns_records transaction execute
60 | fi
61 |
62 | popd >> /dev/null
63 |
--------------------------------------------------------------------------------
/vm/configure_sql.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | if [ "$#" -lt 2 ]; then
20 | echo "Usage: ${BASH_SOURCE[0]} ()"
21 | exit 1
22 | fi
23 |
24 | if ! /google/google-cloud-sdk/bin/gcloud --quiet sql instances list >> /dev/null 2> /dev/null; then
25 | PROJECT=$(gcloud info | grep Project | cut -d"[" -f2 | cut -d"]" -f1)
26 | echo
27 | echo
28 | echo " Error: Google Cloud SQL API has not been enabled for $PROJECT."
29 | echo
30 | echo " 1. Please visit https://console.developers.google.com/apis/api/sqladmin/overview?project=$PROJECT"
31 | echo " 2. Enable API button"
32 | echo " 3. Rerun this script"
33 | echo
34 | exit 1
35 | fi
36 |
37 | # TODO: Once SQL gen 2 is out of beta we may be able to use the proxy.
38 | # sudo wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64
39 | # sudo mv cloud_sql_proxy.linux.amd64 cloud_sql_proxy
40 | # sudo chmod +x cloud_sql_proxy
41 | #
42 | # sudo mkdir -p /cloudsql
43 | # sudo chmod 777 /cloudsql
44 | # sudo ./cloud_sql_proxy -dir=/cloudsql -fuse &
45 |
46 | SQL_INSTANCE=$1
47 | PHABRICATOR_BASE_URI=$2
48 | if [ "$#" -eq 3 ]; then
49 | PHABRICATOR_ALTERNATE_BASE_URI=$3
50 | else
51 | PHABRICATOR_ALTERNATE_BASE_URI=
52 | fi
53 |
54 | # uuid-runtime: required to generate our root password
55 | # jq: required for parsing the sql server json details
56 | sudo apt-get install -y uuid-runtime jq
57 |
58 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
59 |
60 | pushd phabricator >> /dev/null
61 | export SQL_DETAILS="$(/google/google-cloud-sdk/bin/gcloud sql instances describe ${SQL_INSTANCE} --format=json)"
62 | if [ -z "${SQL_DETAILS}" ]; then
63 | echo "Failed to lookup details for the '${SQL_INSTANCE}' Cloud SQL instance. Make sure that you have the SQL API enabled."
64 | exit 1
65 | fi
66 | popd >> /dev/null
67 |
68 | # TODO: Once SQL gen 2 is out of beta we may be able to use the proxy.
69 | # export SQL_PROJECT=$(echo ${SQL_DETAILS} | jq -r '.project')
70 | # export SQL_REGION=$(echo ${SQL_DETAILS} | jq -r '.region')
71 | # export SQL_HOST="/cloudsql/$SQL_PROJECT:$SQL_REGION:$SQL_INSTANCE"
72 |
73 | export SQL_HOST=$(echo ${SQL_DETAILS} | jq -r '.ipAddresses[0].ipAddress')
74 | if [ -z "${SQL_HOST}" ]; then
75 | echo "Failed to create the host of the '${SQL_INSTANCE}' Cloud SQL instance"
76 | exit 1
77 | fi
78 |
79 | export SQL_USER=root
80 | echo "Setting up a connection to ${SQL_INSTANCE} at ${SQL_HOST} as ${SQL_USER}"
81 |
82 | export SQL_PASS="$(uuidgen)"
83 | sudo /google/google-cloud-sdk/bin/gcloud sql instances set-root-password --password "${SQL_PASS}" "${SQL_INSTANCE}"
84 |
85 | pushd /opt/phabricator >> /dev/null
86 |
87 | # Configure Phabricator's connection to the SQL server.
88 | sudo ./bin/config set mysql.host ${SQL_HOST}
89 | sudo ./bin/config set mysql.port 3306
90 | sudo ./bin/config set mysql.user ${SQL_USER}
91 | sudo ./bin/config set mysql.pass ${SQL_PASS}
92 |
93 | # Configure Phabricator's reference to itself.
94 | sudo ./bin/config set phabricator.base-uri ${PHABRICATOR_BASE_URI}
95 | sudo ./bin/config set security.alternate-file-domain ${PHABRICATOR_ALTERNATE_BASE_URI}
96 | sudo ./bin/config set phd.taskmasters 4
97 |
98 | popd >> /dev/null
99 |
100 | echo "Upgrading $SQL_INSTANCE db (this may take a few minutes)..."
101 |
102 | sudo phabricator/bin/storage upgrade --force
103 |
--------------------------------------------------------------------------------
/vm/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # Terminate execution on command failure
18 | set -e
19 |
20 | if [ "$#" -lt 2 ]; then
21 | echo "Usage: ${BASH_SOURCE[0]} ()"
22 | exit 1
23 | fi
24 |
25 | SQL_INSTANCE=$1
26 | PHABRICATOR_BASE_URI=$2
27 |
28 | if [ "$#" -eq 3 ]; then
29 | PHABRICATOR_ALTERNATE_BASE_URI=$3
30 | else
31 | PHABRICATOR_ALTERNATE_BASE_URI=
32 | fi
33 |
34 | confirm() {
35 | echo "Press RETURN to continue, or ^C to cancel.";
36 | read -e ignored
37 | }
38 |
39 | GIT='git'
40 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
41 |
42 | LTS="Ubuntu 10.04"
43 | ISSUE=`cat /etc/issue`
44 | if [[ $ISSUE != Ubuntu* ]]
45 | then
46 | echo "This script is intended for use on Ubuntu, but this system appears";
47 | echo "to be something else. Your results may vary.";
48 | echo
49 | confirm
50 | elif [[ `expr match "$ISSUE" "$LTS"` -eq ${#LTS} ]]
51 | then
52 | GIT='git-core'
53 | fi
54 |
55 | echo "PHABRICATOR UBUNTU INSTALL SCRIPT";
56 | echo "This script will install Phabricator and all of its core dependencies.";
57 | echo "Run it from the directory you want to install into.";
58 | echo
59 |
60 | ROOT=`pwd`
61 | echo "Phabricator will be installed to: ${ROOT}.";
62 |
63 | echo "Testing sudo..."
64 | sudo true
65 | if [ $? -ne 0 ]; then
66 | echo "ERROR: You must be able to sudo to run this script.";
67 | exit 1;
68 | fi;
69 |
70 | echo "Installing dependencies: git, apache, mysql, php...";
71 | echo
72 |
73 | set +x
74 |
75 | # -qq No output except for errors
76 | sudo apt-get -qq update
77 |
78 | # Install git
79 | sudo apt-get install -y git
80 |
81 | # Install mysql
82 | sudo apt-get install -y mysql-client libmysqlclient-dev
83 |
84 | # Install Apache
85 | sudo apt-get install -y apache2
86 |
87 | # Install php
88 | sudo apt-get install -y php5 php5-mysql php5-gd php5-dev php5-curl php-apc php5-cli php5-json
89 |
90 | sudo apt-get clean
91 |
92 | # Enable mod-rewrite
93 | sudo a2enmod rewrite
94 |
95 | HAVEPCNTL=`php -r "echo extension_loaded('pcntl');"`
96 | if [ $HAVEPCNTL != "1" ]
97 | then
98 | echo "Installing pcntl...";
99 | echo
100 | apt-get source php5
101 | PHP5=`ls -1F | grep '^php5-.*/$'`
102 | (cd $PHP5/ext/pcntl && phpize && ./configure && make && sudo make install)
103 | else
104 | echo "pcntl already installed";
105 | fi
106 |
107 | line() {
108 | echo
109 | echo "============================================"
110 | echo "$@"
111 | }
112 |
113 | line "Configuring users..."
114 | bash $DIR/configure_users.sh || exit 1
115 |
116 | line "Configuring submodules..."
117 | bash $DIR/configure_submodules.sh || exit 1
118 |
119 | line "Configuring apache..."
120 | bash $DIR/configure_apache.sh || exit 1
121 |
122 | line "Configuring php..."
123 | bash $DIR/configure_php.sh || exit 1
124 |
125 | line "Configuring pygments..."
126 | bash $DIR/configure_pygments.sh || exit 1
127 |
128 | line "Configuring phabricator..."
129 | bash $DIR/configure_phabricator.sh || exit 1
130 |
131 | line "Configuring hosted repos..."
132 | bash $DIR/configure_hosted_repos.sh || exit 1
133 |
134 | line "Configuring gcloud..."
135 | bash $DIR/configure_gcloud.sh || exit 1
136 |
137 | line "Configuring sql..."
138 | bash $DIR/configure_sql.sh $SQL_INSTANCE $PHABRICATOR_BASE_URI $PHABRICATOR_ALTERNATE_BASE_URI || exit 1
139 |
140 | pushd phabricator >> /dev/null
141 | line "Starting daemons"
142 | sudo su phabricator-daemon -c "./bin/phd restart"
143 | popd >> /dev/null
144 |
145 | line "Restarting apache..."
146 | sudo apachectl restart
147 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Phabricator on Google's Compute Engine
2 |
3 | This script tries its darndest to automate the process of setting up a Phabricator server on
4 | Google's Compute Engine.
5 |
6 | Things that aren't automated:
7 |
8 | - Creating a Cloud engine project.
9 | - Enabling Google Cloud APIs.
10 | - Installing the gcloud APIs on your local machine.
11 | - Buying a domain.
12 | - Updating your domain's NS entries to point to Google's Cloud DNS.
13 | - Signing up for a mailgun account.
14 | - Creating a mailgun domain.
15 |
16 | This repo contains a script that handles most of the rest of the busy work. Let's go over getting a
17 | Compute Engine project started.
18 |
19 | ## Getting started
20 |
21 | ### Create a project
22 |
23 | Visit https://console.developers.google.com/project to create a new project.
24 |
25 | ### Enable APIs
26 |
27 | Visit your project's APIs library:
28 |
29 | https://console.developers.google.com/apis/library?project=your-project-name
30 |
31 | And enable the following:
32 |
33 | 1. Google Compute Engine
34 | 2. Google Cloud SQL API
35 | 3. Google Cloud DNS API
36 |
37 | You don't need to create credentials for either of the above services.
38 |
39 | Estimated time to complete: 2-5 minutes (all manual steps).
40 |
41 | ### Install gcloud tools
42 |
43 | Follow the directions located here: https://cloud.google.com/sdk/?hl=en
44 |
45 | curl https://sdk.cloud.google.com | bash
46 |
47 | NOTE for [fish shell](https://fishshell.com/) users: gcloud doesn't provide fish support out of the
48 | box. You can directly add the gcloud bin to your path by editing config.fish like so:
49 |
50 | vi ~/.config/fish/config.fish
51 | set -x PATH $PATH /path/to/google-cloud-sdk/bin
52 |
53 | Once gcloud has been installed and is available in your PATH (may require restarting terminal), run:
54 |
55 | gcloud init
56 |
57 | This configuration will ask you for the following information:
58 |
59 | - Your login credentials
60 | - A cloud project (pick your phabricator project)
61 | - The default compute zone (pick what's closest to you)
62 | - Whether or not you want to use Google's source hosting. You don't need this for this script.
63 |
64 | Estimated time to complete: 5 minutes (some manual steps).
65 |
66 | ### Create your project's configuration file
67 |
68 | The first time you run the script it will create a default configuration file for your project in
69 | `config/`.
70 |
71 | ./install -p
72 |
73 | ### Run the install script
74 |
75 | Once you've configured your project's config file you can run the install script:
76 |
77 | ./install -p
78 |
79 | Estimated time to complete: 18-20 minutes (totally automated after invocation).
80 |
81 | ### Upgrading phabricator
82 |
83 | To upgrade phabricator you may run:
84 |
85 | ./upgrade -p
86 |
87 | Estimated time to complete: 3 minutes (totally automated after invocation).
88 |
89 | ### Connecting to the phabricator instance
90 |
91 | To ssh into your instance you must run:
92 |
93 | ./ssh -p
94 |
95 | ### Shutting down the server
96 |
97 | TODO: Discuss shutting down compute engine and serving a static "update in progress page."
98 |
99 | ## Custom domains
100 |
101 | Custom domains enable the following features:
102 |
103 | - Email with Mailgun
104 | - Notifications
105 | - Git hosting
106 |
107 | ### Before you start
108 |
109 | - Choose your favorite registrar and purchase a domain name. Ensure that you are able to change the
110 | name servers for your domain.
111 | - Register for Mailgun. [Mailgun](http://www.mailgun.com/) is
112 | [Phabricator's recommended outgoing email service](https://secure.phabricator.com/book/phabricator/article/configuring_outbound_email/).
113 | Register for an account and provide it with your custom domain.
114 |
115 | NOTE: Do not use a subdomain when creating your Mailgun domain. E.g. if your website's name is
116 | `phabricatorplayground.com`, use `phabricatorplayground.com` as the domain name.
117 |
118 | ### Update your configuration
119 |
120 | Modify your `config/` file to set the following values:
121 |
122 | MAILGUN_APIKEY="your api key"
123 | CUSTOM_DOMAIN="yourdomain.com"
124 | CUSTOM_DOMAIN_A_RECORD="ip.1 ip.2 ip.3 ip.4"
125 | CUSTOM_DOMAIN_AAAA_RECORD="ip::1 ip::2 ip::3 ip::4"
126 |
127 | # Note that the above records are space-separated. There should be four for each.
128 |
129 | Re-run the installation script:
130 |
131 | ./install -p
132 |
133 | Follow the displayed steps to register your custom domain with your Cloud Engine project.
134 |
135 | #### Manual step: Change nameservers
136 |
137 | Once the install script completes you must change the name servers for your domain.
138 |
139 | Start by visiting the DNS Zones page of your project:
140 |
141 | https://console.cloud.google.com/networking/dns/zones
142 |
143 | Open your phabricator zone and look at the `NS` values listed. Enter these values in your
144 | registrar's namespace editor for your domain. These changes may take up to 24 hours to propagate.
145 |
146 | You will know once your DNS changes have propagated when you visit your Mailgun project page and
147 | your domain has been verified.
148 |
149 | #### Don't want to wait for propagation?
150 |
151 | If propagation is taking a long time you can set up a temporary mapping by modifying any of the IPs
152 | found at:
153 |
154 | https://console.cloud.google.com/appengine/settings/domains
155 |
156 | to your domain in your `/etc/hosts` file.
157 |
158 | some.ipyourdomain.com
159 |
160 | #### Troubleshooting DNS
161 |
162 | > server DNS address could not be found.
163 |
164 | Ensure that your NS entries for your custom domain on Cloud Engine match the ones set on your
165 | registrar.
166 |
167 | ## License
168 |
169 | Licensed under the Apache 2.0 license. See LICENSE for details.
170 |
--------------------------------------------------------------------------------
/lib/init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | usage() {
18 | echo "Usage: ${BASH_SOURCE[0]} -p "
19 | }
20 |
21 | gcloud version >/dev/null 2>&1 || { echo >&2 "gcloud binary is missing. Download from https://cloud.google.com/sdk/?hl=en"; exit 1; }
22 |
23 | GCLOUD_VERSION=$(gcloud version | grep "^Google" | cut -d' ' -f4 | cut -d'.' -f1)
24 | GITHUB_REPO="https://github.com/GoogleCloudPlatform/compute-phabricator.git"
25 |
26 | if [ "$GCLOUD_VERSION" -lt 102 ]; then
27 | echo "Minimum gcloud version required: 102. Found $GCLOUD_VERSION instead."
28 | exit 1
29 | fi
30 |
31 | OPTIND=1 # Reset in case getopts has been used previously in the shell.
32 |
33 | # Option defaults
34 | PROJECT=""
35 | VERBOSE=0
36 |
37 | while getopts "h?vp:" opt; do
38 | case "$opt" in
39 | h|\?)
40 | usage
41 | exit 0
42 | ;;
43 | v) VERBOSE=1
44 | ;;
45 | p) PROJECT=$OPTARG
46 | ;;
47 | esac
48 | done
49 |
50 | verbose() {
51 | if [ "$VERBOSE" -eq "1" ]; then
52 | echo "$@"
53 | fi
54 | }
55 |
56 | status() {
57 | echo -n "$@"
58 | }
59 |
60 | status_no() {
61 | echo no
62 | }
63 |
64 | status_ok() {
65 | echo OK
66 | }
67 |
68 | if [ -z "$PROJECT" ]; then
69 | verbose "Inferring project from default settings..."
70 | PROJECT=$(gcloud config list 2>/dev/null | grep "^project" | cut -d' ' -f3)
71 |
72 | echo "Inferred project:"
73 | echo
74 | echo " $PROJECT"
75 | echo
76 | echo "If incorrect, please terminate this script and provide a -p argument."
77 | echo "If correct, press enter to continue."
78 | echo
79 | echo "Provide a -p argument to avoid this warning in the future."
80 | read
81 | fi
82 |
83 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
84 | mkdir -p "$DIR/../config"
85 | CONFIG_ROOT_PATH="$( cd "$DIR/../config" && pwd )"
86 | CONFIG_PATH="$CONFIG_ROOT_PATH/$PROJECT"
87 |
88 | # Check existence of a config file for this project.
89 | if [ ! -f "$CONFIG_PATH" ]; then
90 | echo "No config was found."
91 | echo "A standard one has been made for you based off phabricator.sh.template."
92 | echo "Please configure $CONFIG_PATH to your preferences."
93 |
94 | mkdir -p "$CONFIG_ROOT_PATH"
95 | cp $DIR/../phabricator.sh.template "$CONFIG_PATH"
96 | chmod +x $CONFIG_PATH
97 |
98 | default_zone=$(gcloud config list 2>/dev/null | grep "^zone" | cut -d' ' -f3)
99 | if [ ! -z "$default_zone" ]; then
100 | sed -i.bak "s/^ZONE=.*/ZONE=$default_zone/" "$CONFIG_PATH"
101 | rm "$CONFIG_PATH.bak"
102 | fi
103 |
104 | exit 1
105 | fi
106 |
107 | verbose "Reading config from $CONFIG_PATH"
108 | . "$CONFIG_PATH"
109 |
110 | # Verify that a ZONE has been provided.
111 | if [ -z "$ZONE" ]; then
112 | echo "Config file has not specified a ZONE."
113 | echo "Please specify a ZONE in $CONFIG_PATH"
114 | exit 1
115 | fi
116 |
117 | # Colors
118 |
119 | RED='\033[0;31m'
120 | NC='\033[0m'
121 |
122 | logger() {
123 | while read data; do
124 | verbose "$data"
125 | done
126 | }
127 |
128 | # Register aliases methods for interacting with gcloud
129 |
130 | gcloud_project() {
131 | gcloud --project=${PROJECT} --quiet "$@"
132 | }
133 |
134 | gcloud_networks() {
135 | gcloud_project compute networks "$@"
136 | }
137 |
138 | gcloud_instances() {
139 | gcloud_project compute instances "$@"
140 | }
141 |
142 | gcloud_addresses() {
143 | gcloud_project compute addresses "$@"
144 | }
145 |
146 | gcloud_disks() {
147 | gcloud_project compute disks "$@" --zone "$ZONE"
148 | }
149 |
150 | gcloud_attach_disk() {
151 | gcloud_project compute instances attach-disk $VM_NAME "$@" --zone "$ZONE"
152 | }
153 |
154 | gcloud_zones() {
155 | gcloud_project compute zones "$@"
156 | }
157 |
158 | gcloud_dns_zones() {
159 | gcloud_project dns managed-zones "$@"
160 | }
161 |
162 | gcloud_dns_records() {
163 | gcloud_project dns record-sets "$@" --zone="$DNS_NAME"
164 | }
165 |
166 | gcloud_firewall_rules() {
167 | gcloud_project compute firewall-rules "$@"
168 | }
169 |
170 | gcloud_appengine() {
171 | gcloud_project app "$@"
172 | }
173 |
174 | gcloud_sql_instances() {
175 | gcloud_project sql instances "$@"
176 | }
177 |
178 | # SSL utils
179 |
180 | close_ssh() {
181 | status "ssh port is closed? "
182 | if [ "$(gcloud_firewall_rules list | grep "\b$NETWORK_NAME\b" | grep "\btemp-allow-ssh\b")" ]; then
183 | status_no
184 |
185 | status "- Removing temporary $NETWORK_NAME ssh firewall rule..."
186 | gcloud_firewall_rules delete temp-allow-ssh \
187 | 2>&1 | logger || exit 1
188 | fi
189 | status_ok
190 | }
191 |
192 | open_ssh() {
193 | export PORT="22"
194 | if [ ! -z "$(gcloud_instances describe $VM_NAME --zone=$ZONE | grep "ssh-222")" ]; then
195 | PORT="222"
196 | fi
197 |
198 | trap close_ssh EXIT
199 |
200 | if [ -z "$(gcloud_firewall_rules list | grep "\b$NETWORK_NAME\b" | grep "\btemp-allow-ssh\b")" ]; then
201 | status "- Creating temporary $NETWORK_NAME ssh firewall rule..."
202 | gcloud_firewall_rules create temp-allow-ssh \
203 | --allow "tcp:$PORT" \
204 | --network $NETWORK_NAME \
205 | --target-tags "phabricator" \
206 | --source-ranges "0.0.0.0/0" \
207 | 2>&1 | logger || exit 1
208 | fi
209 | status_ok
210 | }
211 |
212 | remote_exec() {
213 | echo "Executing $1..."
214 | gcloud --project=${PROJECT} compute ssh $VM_NAME --zone $ZONE --ssh-flag="-p $PORT" --command "$1" || exit 1
215 | }
216 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/install:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2016-present Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | . lib/init.sh
18 |
19 | # Terminate execution on command failure
20 | set -e
21 |
22 | if [[ ! -z "$CUSTOM_DOMAIN" && "$CUSTOM_DOMAIN_CONFIRMED" != "$PROJECT" ]]; then
23 | echo -e ${RED}
24 | echo "You have provided a custom domain of $CUSTOM_DOMAIN"
25 | echo "In order to configure the domain you will need to perform the following steps:"
26 | echo
27 | echo " 1. Visit https://console.developers.google.com/appengine/settings/domains?project=$PROJECT"
28 | echo
29 | echo " If $CUSTOM_DOMAIN is already listed there then your work is done here, otherwise continue with step 2:"
30 | echo
31 | echo " 2. Visit https://console.developers.google.com/appengine/settings/domains/add?project=$PROJECT"
32 | echo " 3. Register your custom domain."
33 | echo
34 | echo " Learn more about custom domains at https://cloud.google.com/appengine/docs/using-custom-domains-and-ssl?hl=en"
35 | echo -e ${NC}
36 |
37 | echo "Please press enter to confirm that you've registered $CUSTOM_DOMAIN as a custom domain, or Ctrl-C to quit."
38 | read
39 |
40 | if [ $(grep -c "^CUSTOM_DOMAIN_CONFIRMED" $CONFIG_PATH) -ne 0 ]; then
41 | sed -i'.tmp' -e "s/^CUSTOM_DOMAIN_CONFIRMED=.*/CUSTOM_DOMAIN_CONFIRMED=$PROJECT/" $CONFIG_PATH
42 | rm -rf $CONFIG_PATH.tmp
43 | else
44 | echo >> $CONFIG_PATH
45 | echo "CUSTOM_DOMAIN_CONFIRMED=$PROJECT" >> $CONFIG_PATH
46 | fi
47 | fi
48 |
49 | if [[ ! -z "$CUSTOM_DOMAIN" && -z "$CUSTOM_DOMAIN_A_RECORD" ]]; then
50 | echo -e ${RED}
51 | echo "You have provided a custom domain of $CUSTOM_DOMAIN"
52 | echo "but you have not provided the necessary A records."
53 | echo
54 | echo "Retrieve the A records by visiting:"
55 | echo
56 | echo " https://console.developers.google.com/appengine/settings/domains?project=$PROJECT"
57 | echo
58 | echo "Set the semicolon-separated values in CUSTOM_DOMAIN_A_RECORD within your config path:"
59 | echo
60 | echo " $CONFIG_PATH"
61 | echo
62 | echo "Example:"
63 | echo
64 | echo " CUSTOM_DOMAIN_A_RECORD=\"216.239.32.21; 216.239.34.21; 216.239.36.21; 216.239.38.21\""
65 | echo
66 | echo -e ${NC}
67 | exit 1
68 | fi
69 |
70 | if [[ ! -z "$CUSTOM_DOMAIN" && -z "$CUSTOM_DOMAIN_AAAA_RECORD" ]]; then
71 | echo -e ${RED}
72 | echo "You have provided a custom domain of $CUSTOM_DOMAIN"
73 | echo "but you have not provided the necessary AAAA records."
74 | echo
75 | echo "Retrieve the AAAA records by visiting:"
76 | echo
77 | echo " https://console.developers.google.com/appengine/settings/domains?project=$PROJECT"
78 | echo
79 | echo "Set the semicolon-separated values in CUSTOM_DOMAIN_A_RECORD within your config path:"
80 | echo
81 | echo " $CONFIG_PATH"
82 | echo
83 | echo "Example:"
84 | echo
85 | echo " CUSTOM_DOMAIN_A_RECORD=\"2001:4860:4802:32::15; 2001:4860:4802:34::15; 2001:4860:4802:36::15; 2001:4860:4802:38::15\""
86 | echo
87 | echo -e ${NC}
88 | exit 1
89 | fi
90 |
91 | if [[ ! -z "$MAILGUN_APIKEY" && -z "$MAILGUN_SMTP_DOMAIN_KEY_TXT" ]]; then
92 | echo -e ${RED}
93 | echo "You have provided a mailgun API key but no domain key"
94 | echo
95 | echo " Config file: $CONFIG_PATH"
96 | echo " Likely Mailgun url: https://mailgun.com/app/domains/$CUSTOM_DOMAIN"
97 | echo
98 | echo " Search for smtp._domainkey and set its **value** as the value"
99 | echo " of MAILGUN_SMTP_DOMAIN_KEY_TXT"
100 | echo -e ${NC}
101 | exit 1
102 | fi
103 |
104 | # TODO: Might not always be appspot - how do we configure this?
105 | PHABRICATOR_URL=$PROJECT.appspot.com
106 | PHABRICATOR_VERSIONED_URL=1-dot-$PROJECT.appspot.com
107 |
108 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
109 |
110 | status "Checking gcloud auth..."
111 | if [ -z "$(gcloud auth list 2> /dev/null | grep \(active\))" ]; then
112 | status_no
113 |
114 | status " Authenticating gcloud..."
115 | gcloud auth login || { echo "Failed to authenticate gcloud."; exit 1; }
116 | fi
117 | status_ok
118 |
119 | status "APIs..."
120 | if ! gcloud_networks list >> /dev/null 2>&1; then
121 | status_no
122 |
123 | echo
124 | echo " Error: The Compute Engine API has not been enabled for $PROJECT."
125 | echo
126 | echo " Please visit https://console.developers.google.com/apis/api/compute_component/overview?project=$PROJECT"
127 | echo " 2. Enable API button"
128 | echo " 3. Rerun this script"
129 | echo
130 | exit 1
131 | fi
132 |
133 | if ! gcloud_dns_zones list >> /dev/null 2>&1; then
134 | status_no
135 |
136 | echo
137 | echo " Error: Google Cloud DNS API has not been enabled for $PROJECT."
138 | echo
139 | echo " 1. Please visit https://console.developers.google.com/apis/api/dns/overview?project=$PROJECT"
140 | echo " 2. Enable API button"
141 | echo " 3. Rerun this script"
142 | echo
143 | exit 1
144 | fi
145 | status_ok
146 |
147 | status "Network..."
148 | if [ -z "$(gcloud_networks list | grep "\b$NETWORK_NAME\b")" ]; then
149 | status_no
150 | status "- Creating $NETWORK_NAME network..."
151 | gcloud_networks create \
152 | $NETWORK_NAME \
153 | --mode auto \
154 | 2>&1 | logger || exit 1
155 | fi
156 | status_ok
157 |
158 | status "Static external IP..."
159 | if [ -z "$(gcloud_addresses list | grep "\b$ADDRESS_NAME\b")" ]; then
160 | status_no
161 |
162 | status "- Requesting static external IP..."
163 | gcloud_addresses create $ADDRESS_NAME \
164 | 2>&1 | logger || exit 1
165 | fi
166 | status_ok
167 |
168 | STATIC_EXTERNAL_IP=$(gcloud_addresses list | grep "\b$ADDRESS_NAME\b" | cut -d' ' -f3)
169 |
170 | status "Compute instances..."
171 | if [ -z "$(gcloud_instances list | grep "\b$VM_NAME\b")" ]; then
172 | status_no
173 |
174 | status "- Creating $VM_NAME compute instance..."
175 | gcloud_instances create "$VM_NAME" \
176 | --address "$STATIC_EXTERNAL_IP" \
177 | --boot-disk-size "10GB" \
178 | --image "ubuntu-14-04" \
179 | --machine-type "n1-standard-1" \
180 | --network "$NETWORK_NAME" \
181 | --zone "$ZONE" \
182 | --tags "phabricator" \
183 | --scopes sql,cloud-platform \
184 | 2>&1 | logger || exit 1
185 | fi
186 | status_ok
187 |
188 | status " Waiting for compute instance to activate..."
189 | while [ -z "$(gcloud_instances list | grep "\b$VM_NAME\b")" ]; do
190 | sleep 10
191 | done
192 | status_ok
193 |
194 | VM_INTERNAL_IP=$(gcloud_instances list | grep "\b$VM_NAME\b" | awk '{print $4}')
195 | VM_EXTERNAL_IP=$(gcloud_instances list | grep "\b$VM_NAME\b" | awk '{print $5}')
196 |
197 | status "internal IP: $VM_INTERNAL_IP. external IP: $VM_EXTERNAL_IP. "
198 | status_ok
199 |
200 | status "SQL..."
201 | if [ -z "$(gcloud_sql_instances list 2> /dev/null | grep "\b$SQL_NAME\b")" ]; then
202 | status_no
203 |
204 | # TODO: Once 2nd generation SQL is out of beta, move to the db-n1-standard-1 tier.
205 |
206 | status "- Creating $SQL_NAME 1st generation SQL database (may take a few minutes)..."
207 | gcloud_sql_instances create "$SQL_NAME" \
208 | --activation-policy=ALWAYS \
209 | --authorized-networks="$VM_EXTERNAL_IP" \
210 | --assign-ip \
211 | --backup-start-time="00:00" \
212 | --gce-zone "$ZONE" \
213 | --tier="D1" \
214 | --pricing-plan="PACKAGE" \
215 | --database-flags="sql_mode=STRICT_ALL_TABLES,ft_min_word_len=3,max_allowed_packet=33554432" \
216 | 2>&1 | logger || exit 1
217 | fi
218 | status_ok
219 |
220 | status " Verifying SQL..."
221 | SQL_INSTANCE_NAME=$(gcloud_sql_instances list | grep "\b$SQL_NAME\b" | cut -d " " -f 1)
222 | if [ -z "${SQL_INSTANCE_NAME}" ]; then
223 | status_no
224 |
225 | echo "Failed to load the name of the Cloud SQL instance to use for Phabricator"
226 | exit 1
227 | fi
228 | status_ok
229 |
230 | checkdisk() {
231 | name=$1
232 | status "$name disk..."
233 | if [ -z "$(gcloud_disks list | grep "\b$name\b")" ]; then
234 | status_no
235 |
236 | status "- Creating..."
237 | gcloud_disks create \
238 | "$name" \
239 | --size "200" \
240 | --type "pd-standard" \
241 | 2>&1 | logger || exit 1
242 | fi
243 | status_ok
244 |
245 | status "$name disk attached..."
246 | if [ -z "$(gcloud_instances describe $VM_NAME --zone=$ZONE | grep "$name")" ]; then
247 | status_no
248 |
249 | status "- Attaching..."
250 | gcloud_attach_disk \
251 | --disk "$name" \
252 | 2>&1 | logger || exit 1
253 | fi
254 | status_ok
255 | }
256 |
257 | checkdisk "git-repos"
258 | checkdisk "file-storage"
259 |
260 | status "Allow internal http..."
261 | if [ -z "$(gcloud_firewall_rules list | grep "\b$NETWORK_NAME\b" | grep "\ballow-internal-http\b")" ]; then
262 | status_no
263 |
264 | REGION=$(gcloud_zones list | grep $ZONE | awk '{print $2}')
265 | SUBNET_RANGE=$(gcloud_networks subnets list | grep $NETWORK_NAME | grep $REGION | awk '{print $4}')
266 |
267 | status "- Creating firewall rule 'allow-internal-http'..."
268 | gcloud_firewall_rules create \
269 | allow-internal-http \
270 | --allow "tcp:8080" \
271 | --network "$NETWORK_NAME" \
272 | --source-ranges "$SUBNET_RANGE" \
273 | 2>&1 | logger || exit 1
274 | fi
275 | status_ok
276 |
277 | # Sub-domain configuration
278 |
279 | if [ ! -z "$CUSTOM_DOMAIN" ]; then
280 | status "Allow git ssh..."
281 | if [[ ! -z "$GIT_SUBDOMAIN" && -z "$(gcloud_firewall_rules list | grep "\b$NETWORK_NAME\b" | grep "\ballow-git-ssh\b")" ]]; then
282 | status_no
283 |
284 | status "- Creating firewall rule 'allow-git-ssh'..."
285 | gcloud_firewall_rules create \
286 | allow-git-ssh \
287 | --allow "tcp:22" \
288 | --network "$NETWORK_NAME" \
289 | --target-tags "phabricator" \
290 | 2>&1 | logger || exit 1
291 | fi
292 | status_ok
293 |
294 | status "Allow notifications..."
295 | if [[ ! -z "$NOTIFICATIONS_SUBDOMAIN" && -z "$(gcloud_firewall_rules list | grep "\b$NETWORK_NAME\b" | grep "\ballow-notifications\b")" ]]; then
296 | status_no
297 |
298 | status "- Creating firewall rule 'allow-notifications'..."
299 | gcloud_firewall_rules create \
300 | allow-notifications \
301 | --allow "tcp:22280" \
302 | --network "$NETWORK_NAME" \
303 | --target-tags "phabricator" \
304 | 2>&1 | logger || exit 1
305 | fi
306 | status_ok
307 |
308 | # Use the custom domain
309 | PHABRICATOR_URL=$CUSTOM_DOMAIN
310 | TOP_LEVEL_DOMAIN=$(echo $CUSTOM_DOMAIN | rev | cut -d'.' -f-2 | rev)
311 |
312 | status "DNS for $CUSTOM_DOMAIN..."
313 | if [ -z "$(gcloud_dns_zones list 2> /dev/null | grep "\b$DNS_NAME\b")" ]; then
314 | status_no
315 |
316 | status "- Creating DNS zone $DNS_NAME..."
317 | gcloud_dns_zones create \
318 | --dns-name="$TOP_LEVEL_DOMAIN" \
319 | --description="phabricator DNS" \
320 | $DNS_NAME \
321 | 2>&1 | logger || exit 1
322 | fi
323 | status_ok
324 |
325 | # Abort any existing transaction
326 | abort_existing_dns() {
327 | if gcloud_dns_records transaction describe >> /dev/null 2>&1; then
328 | gcloud_dns_records transaction abort 2>&1 | logger
329 | fi
330 | }
331 |
332 | status " Mailgun TXT..."
333 | if [ -z "$(gcloud_dns_records list | grep "\bTXT\b" | grep "mailgun.org")" ]; then
334 | status_no
335 |
336 | abort_existing_dns
337 |
338 | status "- Adding DNS TXT entry 'v=spf1 include:mailgun.org ~all'..."
339 | gcloud_dns_records transaction start \
340 | 2>&1 | logger || exit 1
341 | gcloud_dns_records transaction add \
342 | --name="$TOP_LEVEL_DOMAIN." \
343 | --ttl=21600 \
344 | --type=TXT "v=spf1 include:mailgun.org ~all" \
345 | 2>&1 | logger || exit 1
346 | gcloud_dns_records transaction execute \
347 | 2>&1 | logger || exit 1
348 | fi
349 | status_ok
350 |
351 | status " Mailgun SMTP TXT..."
352 | if [ -z "$(gcloud_dns_records list | grep "\bTXT\b" | grep "k=rsa;")" ]; then
353 | status_no
354 |
355 | abort_existing_dns
356 |
357 | status "- Adding DNS SMTP TXT entry 'smtp._domainkey'..."
358 | gcloud_dns_records transaction start \
359 | 2>&1 | logger || exit 1
360 | gcloud_dns_records transaction add \
361 | --name="smtp._domainkey.$TOP_LEVEL_DOMAIN." \
362 | --ttl=21600 \
363 | --type=TXT "$MAILGUN_SMTP_DOMAIN_KEY_TXT" \
364 | 2>&1 | logger || exit 1
365 | gcloud_dns_records transaction execute \
366 | 2>&1 | logger || exit 1
367 | fi
368 | status_ok
369 |
370 | status " Mailgun CNAME..."
371 | if [ -z "$(gcloud_dns_records list | grep "\bCNAME\b" | grep "mailgun.org")" ]; then
372 | status_no
373 |
374 | abort_existing_dns
375 |
376 | status "- Adding DNS CNAME entry email.$PHABRICATOR_URL. 'mailgun.org'..."
377 | gcloud_dns_records transaction start \
378 | 2>&1 | logger || exit 1
379 | gcloud_dns_records transaction add \
380 | --name="email.$TOP_LEVEL_DOMAIN." \
381 | --ttl=21600 \
382 | --type=CNAME "mailgun.org." \
383 | 2>&1 | logger || exit 1
384 | gcloud_dns_records transaction execute \
385 | 2>&1 | logger || exit 1
386 | fi
387 | status_ok
388 |
389 | status " Mailgun MX..."
390 | if [ -z "$(gcloud_dns_records list | grep "\bMX\b" | grep "mxa.mailgun.org")" ]; then
391 | status_no
392 |
393 | abort_existing_dns
394 |
395 | status "- Adding DNS MX entries for mailgun..."
396 | gcloud_dns_records transaction start \
397 | 2>&1 | logger || exit 1
398 | gcloud_dns_records transaction add \
399 | --name="$TOP_LEVEL_DOMAIN." \
400 | --ttl=21600 \
401 | --type=MX "10 mxa.mailgun.org." "10 mxb.mailgun.org." \
402 | 2>&1 | logger || exit 1
403 | gcloud_dns_records transaction execute \
404 | 2>&1 | logger || exit 1
405 | fi
406 | status_ok
407 |
408 | ensure_record() {
409 | recordtype=$1
410 | status " $recordtype record..."
411 | if [[ -z "$(gcloud_dns_records list | grep "\b$recordtype\b" | grep "^$TOP_LEVEL_DOMAIN.")" ]]; then
412 | status_no
413 |
414 | abort_existing_dns
415 |
416 | status "- Adding $recordtype entry..."
417 | gcloud_dns_records transaction start \
418 | 2>&1 | logger || exit 1
419 | gcloud_dns_records transaction add \
420 | --name="$TOP_LEVEL_DOMAIN." \
421 | --ttl=21600 \
422 | --type="$recordtype" \
423 | "${@:2}" \
424 | 2>&1 | logger || exit 1
425 | gcloud_dns_records transaction execute \
426 | 2>&1 | logger || exit 1
427 | fi
428 | status_ok
429 | }
430 |
431 | if [ ! -z "$CUSTOM_DOMAIN_A_RECORD" ]; then
432 | ensure_record A $CUSTOM_DOMAIN_A_RECORD
433 | fi
434 |
435 | if [ ! -z "$CUSTOM_DOMAIN_AAAA_RECORD" ]; then
436 | ensure_record AAAA $CUSTOM_DOMAIN_AAAA_RECORD
437 | fi
438 |
439 | ensure_subdomain() {
440 | name="$1"
441 | status " Subdomain: $name..."
442 | if [[ -z "$(gcloud_dns_records list | grep "\bA\b" | grep "\b$name.$TOP_LEVEL_DOMAIN.")" ]]; then
443 | status_no
444 |
445 | abort_existing_dns
446 |
447 | status "- Adding DNS subdomain entry $name..."
448 | gcloud_dns_records transaction start \
449 | 2>&1 | logger || exit 1
450 | gcloud_dns_records transaction add \
451 | --name="$name.$TOP_LEVEL_DOMAIN." \
452 | --ttl=60 \
453 | --type=A \
454 | $VM_EXTERNAL_IP \
455 | 2>&1 | logger || exit 1
456 | gcloud_dns_records transaction execute \
457 | 2>&1 | logger || exit 1
458 | fi
459 | status_ok
460 | }
461 |
462 | if [ ! -z "$NOTIFICATIONS_SUBDOMAIN" ]; then
463 | ensure_subdomain "$NOTIFICATIONS_SUBDOMAIN"
464 | fi
465 | if [ ! -z "$GIT_SUBDOMAIN" ]; then
466 | ensure_subdomain "$GIT_SUBDOMAIN"
467 | fi
468 |
469 | exit 1
470 | fi
471 |
472 | pushd $DIR/nginx >> /dev/null
473 |
474 | # TODO: Look into Network Load Balancing as an alternative to App Engine for nginx routing.
475 | # https://cloud.google.com/compute/docs/load-balancing/network/example
476 |
477 | status "Generating nginx.conf..."
478 | if [ -z "$PHABRICATOR_URL" ]; then
479 | status_no
480 |
481 | echo "No phabricator URL found...bailing out"
482 | exit 1
483 | fi
484 |
485 | if [ -z "$VM_INTERNAL_IP" ]; then
486 | status_no
487 |
488 | echo "No internal IP found...bailing out"
489 | exit 1
490 | fi
491 |
492 | cp nginx.conf.template nginx.conf
493 | sed -i.bak -e s/\\\$PHABRICATOR_URL/$PHABRICATOR_URL/ nginx.conf
494 | sed -i.bak -e s/\\\$PHABRICATOR_ALTERNATE_URL/$PHABRICATOR_VERSIONED_URL/ nginx.conf
495 | sed -i.bak -e s/\\\$PHABRICATOR_IP/$VM_INTERNAL_IP/ nginx.conf
496 | rm nginx.conf.bak
497 | status_ok
498 |
499 | COMPUTED_NGINX_SHA=$(find . -type f \( -exec shasum {} \; \) | shasum | cut -d' ' -f1)
500 |
501 | status "nginx deployed..."
502 | if [ "$COMPUTED_NGINX_SHA" != "$NGINX_SHA" ]; then
503 | status_no
504 |
505 | status "deploying nginx..."
506 | gcloud_appengine deploy --version=1 --promote app.yaml || exit 1
507 |
508 | popd >> /dev/null
509 |
510 | NOW=$(date)
511 |
512 | if [ $(grep -c "^NGINX_SHA" $CONFIG_PATH) -ne 0 ]; then
513 | sed -i'.tmp' -e "s/^NGINX_SHA=.*/NGINX_SHA=$COMPUTED_NGINX_SHA # Generated $NOW/" $CONFIG_PATH
514 | rm -rf $CONFIG_PATH.tmp
515 | else
516 | echo >> $CONFIG_PATH
517 | echo "NGINX_SHA=$COMPUTED_NGINX_SHA # Generated $NOW" >> $CONFIG_PATH
518 | fi
519 |
520 | pushd $DIR/nginx >> /dev/null
521 | fi
522 | status_ok
523 |
524 | popd >> /dev/null
525 |
526 | open_ssh
527 |
528 | ################ SERVER COMMANDS START HERE ################
529 |
530 | remote_exec "sudo apt-get -qq update && sudo apt-get install -y git" || exit 1
531 | remote_exec "if [ ! -d phabricator ]; then git clone $GITHUB_REPO; else cd phabricator; git fetch; git rebase origin/master; fi" || exit 1
532 | remote_exec "cd /opt;bash ~/phabricator/vm/install.sh $SQL_NAME http://$PHABRICATOR_URL http://$PHABRICATOR_VERSIONED_URL" || exit 1
533 |
534 | # Configure the startup script.
535 | remote_exec "cp ~/phabricator/vm/startup.sh .; \
536 | sed -i.bak -e s/#TOP_LEVEL_DOMAIN=/TOP_LEVEL_DOMAIN=$TOP_LEVEL_DOMAIN/ startup.sh; \
537 | sed -i.bak -e s/#VM_NAME=/VM_NAME=$VM_NAME/ startup.sh; \
538 | sed -i.bak -e s/#DNS_NAME=/DNS_NAME=$DNS_NAME/ startup.sh" || exit 1
539 |
540 | if [ ! -z "$MAILGUN_APIKEY" ]; then
541 | remote_exec "cd /opt;bash ~/phabricator/vm/configure_mailgun.sh $PHABRICATOR_URL $MAILGUN_APIKEY" || exit 1
542 | fi
543 |
544 | if [ ! -z "$CUSTOM_DOMAIN" ]; then
545 | if [ ! -z "$GIT_SUBDOMAIN" ]; then
546 | remote_exec "sed -i.bak -e s/#GIT_SUBDOMAIN=/GIT_SUBDOMAIN=$GIT_SUBDOMAIN/ startup.sh" || exit 1
547 |
548 | remote_exec "cd /opt;bash ~/phabricator/vm/configure_ssh.sh $GIT_SUBDOMAIN.$TOP_LEVEL_DOMAIN" || exit 1
549 |
550 | # Tag the machine so that we know how to ssh into it in the future
551 | if [ -z "$(gcloud_instances describe $VM_NAME --zone=$ZONE | grep "ssh-222")" ]; then
552 | gcloud_instances add-tags --zone=$ZONE $VM_NAME --tags ssh-222
553 | fi
554 |
555 | port="222"
556 | fi
557 |
558 | if [ ! -z "$NOTIFICATIONS_SUBDOMAIN" ]; then
559 | remote_exec "sed -i.bak -e s/#NOTIFICATIONS_SUBDOMAIN=/NOTIFICATIONS_SUBDOMAIN=$NOTIFICATIONS_SUBDOMAIN/ startup.sh" || exit 1
560 |
561 | remote_exec "cd /opt;sudo bash ~/phabricator/vm/configure_notifications.sh http://$NOTIFICATIONS_SUBDOMAIN.$TOP_LEVEL_DOMAIN" || exit 1
562 | remote_exec "cd /opt/phabricator;sudo su aphlict -c './bin/aphlict restart'" || exit 1
563 | fi
564 | fi
565 |
566 | # Install the startup script.
567 | remote_exec "sudo /google/google-cloud-sdk/bin/gcloud --quiet compute instances add-metadata $VM_NAME --metadata-from-file startup-script=startup.sh" || exit 1
568 |
569 | echo "Visit http://$PHABRICATOR_URL to set up your phabricator instance."
570 | echo "Visit https://console.developers.google.com/permissions/projectpermissions?project=$PROJECT to configure your project's permissions."
571 | echo "Setup complete."
572 |
--------------------------------------------------------------------------------