Created
August 28, 2013 19:18
-
-
Save vanjos/6370080 to your computer and use it in GitHub Desktop.
Set up ec2metata_constants.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* This script gets EC2 metadata and saves it to an ini file. It should be run | |
* on boot before starting application stuff, such as php-fpm or video | |
* processing. | |
*/ | |
// path to put file | |
$path = '/usr/local/viafoura'; | |
$file_path = $path.'/ec2metadata_constants.php'; | |
// make sure the path exists and the file is writable | |
if (!file_exists($path)) | |
{ | |
echo "Directory $path does not exist. Attempting to create it.\n"; | |
$parent = dirname($path); | |
if (!is_writable($parent)) | |
{ | |
echo "Unable to write in $parent.\n"; | |
exit(1); | |
} | |
if (!mkdir('/usr/local/viafoura')) | |
{ | |
echo "Unable to create path $path.\n"; | |
exit(1); | |
} | |
} | |
if (!is_writable($path)) | |
{ | |
echo "Unable to write in $path.\n"; | |
exit(1); | |
} | |
if (file_exists($file_path) && !is_writable($file_path)) | |
{ | |
echo "Unable to write to $file_path.\n"; | |
exit(1); | |
} | |
require_once "../../Viafoura-Core/third_party/r53.php"; | |
$Route53 = new Route53('AKIAJYE5YGIZ2YNGF44Q', 'KBDqD67Tgh9XUPWQVyEwiAPwUIxlfkrpNamgiPdM'); | |
$data = array(); | |
$roles = false; // no known machine role | |
echo "Getting user-data..."; | |
$data = array(); | |
$user_data_url = 'http://169.254.169.254/2011-05-01/user-data'; | |
$dummy_file = $path.'/dummy_ec2_metadata'; | |
$curl = curl_init(); | |
curl_setopt($curl, CURLOPT_URL, $user_data_url); | |
curl_setopt($curl, CURLOPT_HEADER, true); | |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | |
$response = curl_exec($curl); | |
try | |
{ | |
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); | |
if ($http_code !== 200) | |
throw new Exception ("no user data."); | |
$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE); | |
$headers = substr($response, 0, $header_size); | |
$body = substr($response, $header_size); | |
// we use mime file in user data so we can do multiple things with it. | |
// first step is to locate any php bits. | |
$mime_header = 'Content-Type: multipart/mixed; boundary="'; | |
$mime_header_len = strlen($mime_header); | |
if (strpos($body, $mime_header) !== 0) | |
throw new Exception ("user data not in compatible (mime) format"); | |
$boundary_len = strpos($body, '"', $mime_header_len) - $mime_header_len; | |
$boundary = '--' . substr($body, $mime_header_len, $boundary_len); | |
$mime_bits = explode($body, $boundary); | |
foreach ($mime_bits as $bit) | |
{ | |
// a hack to test for | |
// Content-Disposition: attachment; filename="php_user_data" | |
if (strpos('php_user_data') === false) | |
continue; | |
// find the first double newline -- after which is the data we want | |
// and then split the good stuff into lines we can import. | |
$candy = explode("\n", substr($bit, strpos($bit, "\n\n"))); | |
foreach ($candy as $cavity) | |
{ | |
// find the first separator | |
$separator = strpos($cavity, '='); | |
// if no separator, continue | |
if ($separator === false) | |
continue; | |
// switch on the before separator part, and do something with the | |
// after separator, e.g. availability-zone= us-east-1a | |
$key = trim(substr($cavity, 0, $separator)); | |
$value = trim(substr($cavity, $separator + 1)); | |
if (isset($data[$key])) | |
echo " over-writing"; | |
echo " $key..."; | |
$data[$key] = $value; | |
} | |
} | |
echo " done.\n"; | |
} | |
catch (Exception $e) | |
{ | |
echo " ".$e->getMessage()."\n"; | |
} | |
curl_close($curl); | |
echo "Getting EC2 metadata..."; | |
$metadata_url = 'http://169.254.169.254/2011-05-01/meta-data/'; | |
$curl_pieces = array( | |
'ami-id' => 'ami-id', | |
'availability-zone' => 'placement/availability-zone', | |
'instance-id' => 'instance-id', | |
'instance-type' => 'instance-type', | |
'local-hostname' => 'local-hostname', | |
'local-ipv4' => 'local-ipv4', | |
'public-hostname' => 'public-hostname', | |
'public-ipv4' => 'public-ipv4', | |
'security-groups' => 'security-groups' | |
); | |
$curl = curl_multi_init(); | |
$curl_handles = array(); | |
foreach ($curl_pieces as $item => $url_piece) | |
{ | |
$curl_handles[$item] = curl_init($metadata_url . $url_piece); | |
curl_setopt($curl_handles[$item], CURLOPT_RETURNTRANSFER, true); | |
curl_multi_add_handle($curl, $curl_handles[$item]); | |
} | |
// execute all curl queries simultaneously and continue when complete | |
$active = null; | |
do | |
{ | |
$mrc = curl_multi_exec($curl, $active); | |
} while ($mrc == CURLM_CALL_MULTI_PERFORM); | |
while ($active && $mrc == CURLM_OK) | |
{ | |
if (curl_multi_select($curl) != -1) | |
{ | |
do | |
{ | |
$mrc = curl_multi_exec($curl, $active); | |
} while ($mrc == CURLM_CALL_MULTI_PERFORM); | |
} | |
} | |
// store the results of the curls | |
foreach ($curl_pieces as $item => $url_piece) | |
{ | |
$http_code = curl_getinfo($curl_handles[$item], CURLINFO_HTTP_CODE); | |
if ($http_code !== 200) | |
continue; | |
if (isset($data[$item])) | |
echo " over-writing"; | |
echo " $item..."; | |
$data[$item] = curl_multi_getcontent($curl_handles[$item]); | |
curl_multi_remove_handle($curl, $curl_handles[$item]); | |
} | |
curl_multi_close($curl); | |
echo " done.\n"; | |
if (file_exists($dummy_file) && is_readable($dummy_file)) | |
{ | |
echo "Parsing EC2 metadata dummy file $dummy_file..."; | |
$candy = explode("\n", file_get_contents($dummy_file)); | |
foreach ($candy as $cavity) | |
{ | |
// find the first separator | |
$separator = strpos($cavity, '='); | |
// if no separator, continue | |
if ($separator === false) | |
continue; | |
// switch on the before separator part, and do something with the | |
// after separator, e.g. availability-zone= us-east-1a | |
$key = trim(substr($cavity, 0, $separator)); | |
$value = trim(substr($cavity, $separator + 1)); | |
if (isset($data[$key])) | |
echo " over-writing"; | |
echo " $key..."; | |
$data[$key] = $value; | |
} | |
echo " done.\n"; | |
} | |
// set some default values for variables used later | |
$av_zone = 'unknown-avzone'; | |
$instance_id = 'unknown-instance'; | |
$local_hostname = 'unknown-internal-hostname'; | |
$public_hostname = 'unknown-public-hostname'; | |
$security_groups = 'unknown-security-groups'; | |
// start building string for file... | |
$file_data = "<?php\n"; | |
// loop through each retrieved value | |
foreach ($data as $key => $value) | |
{ | |
switch ($key) | |
{ | |
case 'roles': | |
$file_data .= "define ('MACHINE_ROLES', '$value');\n"; | |
$roles = $value; | |
break; | |
case 'ami-id': | |
$file_data .= "define ('EC2_AMI_ID', '$value');\n"; | |
break; | |
case 'availability-zone': | |
$file_data .= "define ('EC2_AVAILABILITY_ZONE', '$value');\n"; | |
$av_zone = $value; | |
break; | |
case 'instance-id': | |
$file_data .= "define ('EC2_INSTANCE_ID', '$value');\n"; | |
$instance_id = $value; | |
break; | |
case 'instance-type': | |
$file_data .= "define ('EC2_INSTANCE_TYPE', '$value');\n"; | |
break; | |
case 'local-hostname': | |
$file_data .= "define ('EC2_LOCAL_HOSTNAME', '$value');\n"; | |
$local_hostname = $value; | |
break; | |
case 'local-ipv4': | |
$file_data .= "define ('EC2_LOCAL_IPV4', '$value');\n"; | |
break; | |
case 'public-hostname': | |
$file_data .= "define ('EC2_PUBLIC_HOSTNAME', '$value');\n"; | |
$public_hostname = $value; | |
break; | |
case 'public-ipv4': | |
$file_data .= "define ('EC2_PUBLIC_IPV4', '$value');\n"; | |
break; | |
case 'security-groups': | |
$file_data .= "define ('EC2_SECURITY_GROUPS', '$value');\n"; | |
$security_groups = $value; | |
break; | |
default: | |
// do nothing... we ought to ignore unknown values... | |
} | |
} | |
// live, staging, or dev? | |
switch ($security_groups) | |
{ | |
case 'FFmpeg+Live': | |
case 'Galera+Live': | |
case 'Task+Live': | |
case 'Web+Live': | |
$environment = 'live'; | |
break; | |
case 'FFmpeg+Staging': | |
case 'Galera+Staging': | |
case 'Task+Staging': | |
case 'Web+Staging': | |
$environment = 'staging'; | |
break; | |
case 'FFmpeg+Dev': | |
case 'Galera+Dev': | |
case 'Task+Dev': | |
case 'Web+Dev': | |
$environment = 'dev'; | |
break; | |
default: | |
$environment = 'unknown-lsd'; | |
} | |
$file_data .= "define ('ENVIRONMENT', '$environment');\n"; | |
// Determine master database hosts based on region. By using the region we'll, | |
// automatically support being launched in new availability zones not defined | |
// in the script. Of course, new regions will require defining master hosts | |
// here. | |
// us-east-1a => us-east | |
$region = substr($av_zone, 0, strpos($av_zone, '-', strpos($av_zone, '-') + 1)); | |
switch ($region) | |
{ | |
case 'us-east': | |
$db_master_avs = 'us-east-1a;us-east-1d;us-east-1e'; | |
default: | |
} | |
$file_data .= "define ('DB_MASTER_AV_ZONES', '$db_master_avs');\n"; | |
// Let's do the same as above, but for Cassandra now | |
switch ($region) | |
{ | |
case 'us-east': | |
$cassandra_avs = ($environment === 'dev') ? 'us-east-1a;us-east-1e' : 'us-east-1a;us-east-1d;us-east-1e'; | |
default: | |
} | |
$file_data .= "define ('CASSANDRA_AV_ZONES', '$cassandra_avs');\n"; | |
file_put_contents($file_path, $file_data); | |
echo "Created metadata file at $file_path\n"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment