summaryrefslogtreecommitdiff
path: root/buildscripts/launch_evergreen_ec2_instance.sh
blob: 7562e5ab79af863d7ffe9f3781ff0c39c34cb77a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/bin/bash
# Script used to clone an AWS EC2 instance in Evergreen from the current variant.
# Currently only supports Windows & Linux.
# See _usage_ for how this script should be invoked.

set -o errexit

# Default options
tag_name="Evergreen AMI"

# _usage_: Provides usage infomation
function _usage_ {
  cat << EOF
usage: $0 options
This script supports the following parameters for Windows & Linux platforms:
  -k <ssh_key_id>,     [REQUIRED] The ssh key id used to access the new AWS EC2 instance.
  -y <aws_ec2_yml>,    [REQUIRED] YAML file name where to store the new AWS EC2 instance
                       information. This file will be used in etc/evergreen.yml for
                       macro expansion of variables used in other functions.
  -s <security_group>, [OPTIONAL] The security group to be used for the new AWS EC2 instance.
                       To specify more than one group, invoke this option each time.
  -t <tag_name>,       [OPTIONAL] The tag name of the new AWS EC2 instance.
EOF
}

# Parse command line options
while getopts "k:s:t:y:?" option
do
   case $option in
     k)
        ssh_key_id=$OPTARG
        ;;
     s)
        sec_groups="$sec_groups $OPTARG"
        ;;
     t)
        tag_name=$OPTARG
        ;;
     y)
        aws_ec2_yml=$OPTARG
        ;;
     \?|*)
        _usage_
        exit 0
        ;;
    esac
done

if [ -z $aws_ec2_yml ]; then
  echo "Must specify aws_ec2_yml file"
  exit 1
fi

if [ -z $ssh_key_id ]; then
  echo "Must specify ssh_key_id"
  exit 1
fi

for sec_group in $sec_groups
do
  security_groups="$security_groups --securityGroup $sec_group"
done

# Get the AMI information on the current host so we can launch a similar EC2 instance.
# See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#instancedata-data-retrieval
aws_metadata_url="http://169.254.169.254/latest/meta-data"
ami=$(curl -s $aws_metadata_url/ami-id)
instance_type=$(curl -s $aws_metadata_url/instance-type)
echo "AMI EC2 info: $ami $instance_type"

data_df=$(df -BG -T /data | tail -n1 | tr -s ' ')
base_device_name=$(echo $data_df | cut -f1 -d ' ' | sed -e 's/.*\///g')
fstype=$(echo $data_df | cut -f2 -d ' ')
device_size=$(echo $data_df | cut -f3 -d ' ' | cut -f1 -d "G" | cut -f1 -d ".")
if [[ -z "$base_device_name" || -z "$fstype" || -z "$device_size" ]]; then
  echo "Could not detect /data mount point, one of the following are not detected:"
  echo "base_device_name: '$base_device_name' fstype: '$fstype' device_size: '$device_size'"
  exit 1
fi

# Linux variants have block device mappings, so discover the mounted drives.
if [ $(uname) = "Linux" ]; then
  devices_info="$base_device_name;$fstype;$device_size"

  is_raid_device=$(grep -s active /proc/mdstat | grep $base_device_name) || true
  if [ ! -z "$is_raid_device" ]; then
    raid_device_name=$base_device_name
    raid_devices=$(lsblk | grep $raid_device_name -B1 | cut -f1 -d ' ' | grep -v $raid_device_name | tr '\n\r' ' ')
    devices_info=
    for device in $raid_devices
    do
      data_device=$(lsblk -o NAME,SIZE | grep $device | tr -s ' ')
      device_size=$(echo $data_device | cut -f2 -d ' ' | cut -f1 -d "G" | cut -f1 -d ".")
      devices_info="$devices_info $device;$fstype;$device_size"
    done
  fi

  # Discover FS options on device, for now, only supports:
  #  - XFS options: crc finobt
  if [ $fstype = "xfs" ]; then
    xfs_info=$(xfs_info /dev/$base_device_name)
    xfs_option_choices="crc finobt"
    opt_num=0
    opt_sep=""
    for xfs_option_choice in $xfs_option_choices
    do
      opt_grep=$(echo $xfs_info | grep $xfs_option_choice) || true
      if [ ! -z "$opt_grep" ]; then
        let "opt_num=opt_num+1"
        if [ $opt_num -gt 1 ]; then
          opt_sep=","
        fi
        xfs_val=$(echo $opt_grep | sed -e "s/.*$xfs_option_choice=//; s/ .*//")
        xfs_options="$xfs_options$opt_sep$xfs_option_choice=$xfs_val"
      fi
    done
    if [ ! -z "$xfs_options" ]; then
      fs_options="-m $xfs_options"
    fi
  fi
  # Specify the Block devices and sizes to be attached to the EC2 instance.
  for info in $devices_info
  do
    device=$(echo $info | cut -f1 -d ';')
    size=$(echo $info | cut -f3 -d ';')
    device_names=$(echo "$device_names $device" | sed -e 's/^ *//; s/ *$//')
    block_device_option="$block_device_option --blockDevice $device $size"
  done
elif [ "Windows_NT" = "$OS" ]; then
  # We use 'xvdf' as the first available device for the EBS volume, which is mounted on 'd:'
  # See http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/device_naming.html
  device="xvdf"
  device_names="d"
  devices_info="$device;$fstype;$device_size"
  block_device_option="--blockDevice $device $device_size"
fi

echo "Devices: $devices_info"

# Launch a new instance.
aws_ec2=$(python buildscripts/aws_ec2.py \
          --ami $ami                     \
          --instanceType $instance_type  \
          --keyName $ssh_key_id          \
          --mode create                  \
          $security_groups               \
          --tagName "$tag_name"          \
          --tagOwner "$USER"             \
          $block_device_option | tr -cd "[:print:]\n")
echo "Spawned new AMI EC2 instance: $aws_ec2"

# Get new instance ID & ip_address
instance_id=$(echo $aws_ec2 | sed -e "s/.*instance_id: //; s/ .*//")
ip_address=$(echo $aws_ec2 | sed -e "s/.*private_ip_address: //; s/ .*//")

# Save AWS information on spawned EC2 instance to be used as an expansion macro.
echo "instance_id: $instance_id" > $aws_ec2_yml
echo "ami: $ami" >> $aws_ec2_yml
echo "instance_type: $instance_type" >> $aws_ec2_yml
echo "ip_address: $ip_address" >> $aws_ec2_yml
echo "device_names: $device_names" >> $aws_ec2_yml
echo "raid_device_name: $raid_device_name" >> $aws_ec2_yml
echo "fstype: $fstype" >> $aws_ec2_yml
echo "fs_options: $fs_options" >> $aws_ec2_yml