Nicolas Noble | ddef246 | 2015-01-06 18:08:25 -0800 | [diff] [blame] | 1 | #!/bin/bash |
Craig Tiller | 8342881 | 2015-02-16 12:13:57 -0800 | [diff] [blame] | 2 | |
Craig Tiller | 0605995 | 2015-02-18 08:34:56 -0800 | [diff] [blame] | 3 | # Copyright 2015, Google Inc. |
Craig Tiller | 8342881 | 2015-02-16 12:13:57 -0800 | [diff] [blame] | 4 | # All rights reserved. |
| 5 | # |
| 6 | # Redistribution and use in source and binary forms, with or without |
| 7 | # modification, are permitted provided that the following conditions are |
| 8 | # met: |
| 9 | # |
| 10 | # * Redistributions of source code must retain the above copyright |
| 11 | # notice, this list of conditions and the following disclaimer. |
| 12 | # * Redistributions in binary form must reproduce the above |
| 13 | # copyright notice, this list of conditions and the following disclaimer |
| 14 | # in the documentation and/or other materials provided with the |
| 15 | # distribution. |
| 16 | # * Neither the name of Google Inc. nor the names of its |
| 17 | # contributors may be used to endorse or promote products derived from |
| 18 | # this software without specific prior written permission. |
| 19 | # |
| 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 | |
Nicolas Noble | ddef246 | 2015-01-06 18:08:25 -0800 | [diff] [blame] | 32 | # Startup script that initializes a grpc-dev GCE machine. |
| 33 | # |
| 34 | # A grpc-docker GCE machine is based on docker container image. |
| 35 | # |
murgatroid99 | 975a07b | 2015-02-02 14:10:42 -0800 | [diff] [blame] | 36 | # On startup, it copies the grpc dockerfiles to a local directory, and update its address. |
Nicolas Noble | ddef246 | 2015-01-06 18:08:25 -0800 | [diff] [blame] | 37 | |
| 38 | # _load_metadata curls a metadata url |
| 39 | _load_metadata() { |
| 40 | local metadata_root=http://metadata/computeMetadata/v1 |
| 41 | local uri=$1 |
| 42 | [[ -n $uri ]] || { echo "missing arg: uri" >&2; return 1; } |
| 43 | |
| 44 | if [[ $uri =~ ^'attributes/' ]] |
| 45 | then |
| 46 | for a in $(curl -H "X-Google-Metadata-Request: True" $metadata_root/instance/attributes/) |
| 47 | do |
| 48 | [[ $uri =~ "/$a"$ ]] && { curl $metadata_root/instance/$uri -H "X-Google-Metadata-Request: True"; return; } |
| 49 | done |
| 50 | fi |
| 51 | |
| 52 | # if the uri is a full request uri |
| 53 | [[ $uri =~ ^$metadata_root ]] && { curl $uri -H "X-Google-Metadata-Request: True"; return; } |
| 54 | } |
| 55 | |
| 56 | _source_gs_script() { |
| 57 | local script_attr=$1 |
| 58 | [[ -n $script_attr ]] || { echo "missing arg: script_attr" >&2; return 1; } |
| 59 | |
| 60 | local gs_uri=$(_load_metadata "attributes/$script_attr") |
| 61 | [[ -n $gs_uri ]] || { echo "missing metadata: $script_attr" >&2; return 1; } |
| 62 | |
| 63 | local out_dir='/var/local/startup_scripts' |
| 64 | local script_path=$out_dir/$(basename $gs_uri) |
| 65 | mkdir -p $out_dir |
| 66 | gsutil cp $gs_uri $script_path || { |
| 67 | echo "could not cp $gs_uri -> $script_path" |
| 68 | return 1 |
| 69 | } |
| 70 | chmod a+rwx $out_dir $script_path |
| 71 | source $script_path |
| 72 | } |
| 73 | |
Tim Emiola | b08dcfa | 2015-02-04 02:47:36 -0800 | [diff] [blame] | 74 | # Args: |
| 75 | # $1: numerator |
| 76 | # $2: denominator |
| 77 | # $3: threshold (optional; defaults to $THRESHOLD) |
| 78 | # |
| 79 | # Returns: |
| 80 | # 1 if (numerator / denominator > threshold) |
| 81 | # 0 otherwise |
| 82 | _gce_disk_cmp_ratio() { |
| 83 | local DEFAULT_THRESHOLD="1.1" |
| 84 | local numer="${1}" |
| 85 | local denom="${2}" |
| 86 | local threshold="${3:-${DEFAULT_THRESHOLD}}" |
| 87 | |
| 88 | if `which python > /dev/null 2>&1`; then |
| 89 | python -c "print(1 if (1. * ${numer} / ${denom} > ${threshold}) else 0)" |
| 90 | else |
| 91 | echo "Can't find python; calculation not done." 1>&2 |
| 92 | return 1 |
| 93 | fi |
| 94 | } |
| 95 | |
| 96 | # Repartitions the disk or resizes the file system, depending on the current |
| 97 | # state of the partition table. |
| 98 | # |
| 99 | # Automates the process described in |
| 100 | # - https://cloud.google.com/compute/docs/disks/persistent-disks#repartitionrootpd |
| 101 | _gce_disk_maybe_resize_then_reboot() { |
| 102 | # Determine the size in blocks, of the whole disk and the first partition. |
| 103 | local dev_sda="$(fdisk -s /dev/sda)" |
| 104 | local dev_sda1="$(fdisk -s /dev/sda1)" |
| 105 | local dev_sda1_start="$(sudo fdisk -l /dev/sda | grep /dev/sda1 | sed -e 's/ \+/ /g' | cut -d' ' -f 3)" |
| 106 | |
| 107 | # Use fdisk to |
| 108 | # - first see if the partion 1 is using as much of the disk as it should |
| 109 | # - then to resize the partition if it's not |
| 110 | # |
| 111 | # fdisk(1) flags: |
| 112 | # -c: disable DOS compatibility mode |
| 113 | # -u: change display mode to sectors (from cylinders) |
| 114 | # |
| 115 | # fdisk(1) commands: |
| 116 | # d: delete partition (automatically selects the first one) |
| 117 | # n: new partition |
| 118 | # p: primary |
| 119 | # 1: partition number |
| 120 | # $dev_sda1_start: specify the value for the start sector, the default may be incorrect |
| 121 | # <1 blank lines>: accept the defaults for end sectors |
| 122 | # w: write partition table |
| 123 | if [ $(_gce_disk_cmp_ratio "${dev_sda}" "${dev_sda1}") -eq 1 ]; then |
| 124 | echo "$FUNCNAME: Updating the partition table to use full ${dev_sda} instead ${dev_sda1}" |
| 125 | cat <<EOF | fdisk -c -u /dev/sda |
| 126 | d |
| 127 | n |
| 128 | p |
| 129 | 1 |
| 130 | $dev_sda1_start |
| 131 | |
| 132 | w |
| 133 | EOF |
| 134 | echo "$FUNCNAME: ... updated the partition table" |
| 135 | shutdown -r now |
| 136 | return 0 |
| 137 | fi |
| 138 | |
| 139 | # After repartitioning, use resize2fs to expand sda1. |
| 140 | local df_size="$(df -B 1K / | grep ' /$' | sed -e 's/ \+/ /g' | cut -d' ' -f 2)" |
| 141 | if [ $(_gce_disk_cmp_ratio "${dev_sda}" "${df_size}") -eq 1 ]; then |
| 142 | echo "$FUNCNAME: resizing the partition to make full use of it" |
| 143 | resize2fs /dev/sda1 |
| 144 | echo "$FUNCNAME: ... resize completed" |
| 145 | fi |
| 146 | } |
| 147 | |
Nicolas Noble | ddef246 | 2015-01-06 18:08:25 -0800 | [diff] [blame] | 148 | main() { |
Tim Emiola | b08dcfa | 2015-02-04 02:47:36 -0800 | [diff] [blame] | 149 | _gce_disk_maybe_resize_then_reboot |
Nicolas Noble | ddef246 | 2015-01-06 18:08:25 -0800 | [diff] [blame] | 150 | local script_attr='shared_startup_script_url' |
| 151 | _source_gs_script $script_attr || { |
| 152 | echo "halting, script 'attributes/$script_attr' could not be sourced" |
| 153 | return 1 |
| 154 | } |
| 155 | grpc_dockerfile_pull |
| 156 | chmod -R a+rw /var/local/dockerfile |
| 157 | |
| 158 | # Install git and emacs |
| 159 | apt-get update && apt-get install -y git emacs || return 1 |
| 160 | |
Nicolas Noble | ddef246 | 2015-01-06 18:08:25 -0800 | [diff] [blame] | 161 | # Startup the docker registry |
| 162 | grpc_docker_launch_registry && grpc_docker_pull_known |
| 163 | |
| 164 | # Add a sentinel file to indicate that startup has completed. |
| 165 | local sentinel_file=/var/log/GRPC_DOCKER_IS_UP |
| 166 | touch $sentinel_file |
| 167 | } |
| 168 | |
| 169 | set -x |
Craig Tiller | ce5021b | 2015-02-18 09:25:21 -0800 | [diff] [blame] | 170 | main "$@" |