/** * keypairList() */ public function keypairList() { $this->Out->debug(__METHOD__,func_get_args()); $key = array(); foreach($this->getNames() as $name) { $table[] = array( 'definition_name' => $name, 'region' => $this->getAttribute($name,'region'), 'private_key' => $this->getAttribute($name,'private_key'), ); } $this->Out->msg(); $this->Out->table($table); return $table; }
/** * packageList() */ public function packageList() { $this->Out->debug(__METHOD__,func_get_args()); $package_list = $this->getNames(); $table = array(); foreach($package_list as $package_name) { $table[] = array( 'name' => $package_name, 'source_path' => $this->getAttribute($package_name,'source_path'), 'excludes' => $this->getAttribute($package_name,'excludes'), 'install_path' => $this->getAttribute($package_name,'install_path'), ); } $this->Out->msg(); $this->Out->table($table); return $table; }
/** * outCommandUsage() * * @param string $command_name */ public function outCommandUsage($command_name) { $this->Out->debug(__METHOD__,func_get_args()); // Display each line item of help $is_first_line = true; foreach($this->command_metas[$command_name]['sub_commands'] as $sub_command=>$sub_command_data) { if(isset($sub_command_data['__usage'])) { if($is_first_line) { $this->Out->msg('Usage: ',false); $is_first_line = false; } else { $this->Out->msg(' ',false); } $this->Out->msg($command_name.' '.$sub_command.' '.$sub_command_data['__usage']); } } $this->Out->msg(); }
/** * getData * * @param string $address_id * @param bool $update */ public function getData($address_id=null,$update=false) { $this->Out->debug(__METHOD__,func_get_args()); if($update || empty($this->data)) { $this->Out->msg('Refreshing cloud address resource data',false); // Empty any pre existing data first $this->data = null; // Obtain data via update or local cache $response = null; try { if($update) { $response = $this->Cloud->EC2->cache(-1)->describe_addresses(); } else { $response = $this->Cloud->EC2->cache($this->Cloud->config['aws']['cache_seconds'].' seconds')->describe_addresses(); } } catch (RequestCore_Exception $e) {} if(empty($response) || !$response->isOK() || !isset($response->{'body'})) { $this->Out->error('Unable to obtain cloud address data'); return false; } $this->data = $response->{'body'}; $this->Out->msg(' - done'); } // Parse the response into a slightly more manageable/useful structure for us $addresses = array(); if(isset($this->data->{'addressesSet'}->{'item'})) { // Addresses foreach($this->data->{'addressesSet'}->{'item'} as $address) { if(isset($this->Cloud->config['ec2']['region']) && !empty($this->Cloud->config['ec2']['region'])) { $region = $this->Cloud->config['ec2']['region']; } else { // Minor kludge alert... $region = 'unknown'; } // Extract the little bits of data we want $addresses[(string) $address->{'publicIp'}] = array( 'instanceId' => (string) $address->{'instanceId'}, 'region' => $region, 'name' => $this->getAttributeFromConfig((string) $address->{'publicIp'},'name') ); } } //print_r($this->data); //print_r($addresses); if(!empty($address_id)) { if(isset($addresses[$address_id])) { return array( $address_id => $addresses[$address_id] ); } return array(); } return $addresses; }
/** * getData() * * @param string $volume_id * @param bool $update */ public function getData($volume_id=null,$update=false) { $this->Out->debug(__METHOD__,func_get_args()); if($update || empty($this->data)) { $last_out_has_new_line = true; if(!$this->Out->last_out_has_new_line) { $last_out_has_new_line = false; $this->Out->msg(' >> ',false); } $this->Out->msg('Refreshing cloud volume resource data',false); // Empty any pre existing data first $this->data = null; // Obtain data via update or local cache $response = null; try { if($update) { $response = $this->Cloud->EC2->cache(-1)->describe_volumes(); } else { $response = $this->Cloud->EC2->cache($this->Cloud->config['aws']['cache_seconds'].' seconds')->describe_volumes(); } } catch (RequestCore_Exception $e) {} if(empty($response) || !$response->isOK() || !isset($response->{'body'})) { $this->Out->error('Unable to obtain cloud volume data'); return false; } $this->data = $response->{'body'}; if($last_out_has_new_line) { $this->Out->msg(' - done'); } else { $this->Out->msg(' - done',false); } } // Parse the response into a slightly more manageable/useful structure for us $volumes = array(); if(isset($this->data->{'volumeSet'}->{'item'})) { // Reservations foreach($this->data->{'volumeSet'}->{'item'} as $volume) { // Extract the tags attached to this instance $tags = array(); if(isset($volume->tagSet)) { foreach($volume->tagSet->item as $tag) { $tags[(string)$tag->{'key'}] = (string)$tag->{'value'}; } } // Extract the attachment this volume is connected to $attachments = array(); foreach($volume->attachmentSet->item as $attachment) { // Weird - can an EBS really be attached to // more than one instance or is this just and // hopeful forward engineering at AWS? if(isset($attachment->volumeId)) { $attachments[] = array( //'volumeId' => (string) $attachment->volumeId, 'instanceId' => (string) $attachment->instanceId, 'device' => (string) $attachment->device, 'status' => (string) $attachment->status, 'attachTime' => strtotime((string) $attachment->attachTime), 'deleteOnTermination'=> (string) $attachment->deleteOnTermination, ); } } // Catch the situation we don't expect where a volume is attached to more than one instance if(isset($attachments[1])) { $this->Out->error('Unexpected API response - Volume appears to be attached to more than one instance: '.$attachments['volumeId']); exit(1); } if(isset($attachments[0])) { $volumes[(string) $volume->volumeId] = $attachments[0]; } $volumes[(string) $volume->volumeId]['size'] = (string) $volume->size; $volumes[(string) $volume->volumeId]['snapshotId'] = (string) $volume->snapshotId; $volumes[(string) $volume->volumeId]['availabilityZone'] = (string) $volume->availabilityZone; $volumes[(string) $volume->volumeId]['status'] = (string) $volume->status; $volumes[(string) $volume->volumeId]['createTime'] = strtotime((string) $volume->createTime); $volumes[(string) $volume->volumeId]['tags'] = !empty($tags) ? $tags : null; } } //print_r($this->data); //print_r($volumes); if(!empty($volume_id)) { if(isset($volumes[$volume_id])) { return array( $volume_id => $volumes[$volume_id] ); } return array(); } return $volumes; }
/** * doPackageUserDataScripts * * @param array $user_data_scripts * @param bool $do_compress * @param bool $do_remove_empty_lines */ public function doPackageUserDataScripts($user_data_scripts,$do_compress=true,$do_remove_empty_lines=false) { $script = '#!/bin/bash'."\n"; $count = 0; foreach($user_data_scripts as $user_data_script) { $count++; if($do_remove_empty_lines) { $new_user_data_script = ''; foreach(split("\n",$user_data_script) as $line) { $line = str_replace("\r",'',$line); $line = preg_replace("/^\s+/",'',$line); if(!empty($line) && !preg_match("/^#/",$line)) { $new_user_data_script .= $line."\n"; } } $user_data_script = $new_user_data_script; //$this->Out->msg($user_data_script); } $script .= "\n".'# == '.$this->Cloud->name.' == '.$count.' of '.count($user_data_scripts).' == #'."\n"; $script .= $user_data_script; } $temp_file = tempnam(sys_get_temp_dir(),$this->Cloud->name.'_'); file_put_contents($temp_file,$script); // wrap this whole thing in a set of calls to base64 + gzip if($do_compress) { // CLOUD_WRAP_SCRIPT=/tmp/cloud_wrap_script.`date +%s` // echo "H4sIAGhncVACA1NW1E/KzNNPSizO4OJKTc7IV1DKSM3JyVcozy/KSVFU4uICAGxwMrYiAAAA" | base64 --decode | gunzip > $CLOUD_WRAP_SCRIPT // /bin/bash $CLOUD_WRAP_SCRIPT // rm -f $CLOUD_WRAP_SCRIPT $script_data = $this->Cloud->SystemCommand->exec("cat ".$temp_file." | gzip -9 -c | base64 --wrap=0"); $script = '#!/bin/bash'."\n"; $script .= 'CLOUDCLI_WRAP=/tmp/cloudcli_wrap.`date +%s`'."\n"; $script .= 'echo "'.$script_data.'" | base64 --decode | gunzip > $CLOUDCLI_WRAP'."\n"; $script .= '/bin/bash $CLOUDCLI_WRAP &> /var/log/cloudcli.log'."\n"; $script .= 'rm -f $CLOUDCLI_WRAP'."\n"; // rewrite the wrapped script file file_put_contents($temp_file,$script); } // There is a 16KB limit on the user data string if(strlen($script) > (16*1024)) { $this->Out->error('UserData content is greater than 16KB - you must find a way to reduce!'); return false; } else { $this->Out->msg('UserData content size: '.strlen($script).' bytes'); } chmod($temp_file,0755); return $temp_file; }
/** * getData * * * @param string $spot_id * @param bool $update */ public function getData($spot_id=null,$update=false) { $this->Out->debug(__METHOD__,func_get_args()); if($update || empty($this->data)) { $last_out_has_new_line = true; if(!$this->Out->last_out_has_new_line) { $last_out_has_new_line = false; $this->Out->msg(' >> ',false); } $this->Out->msg('Refreshing cloud spot request resource data',false); // Empty any pre existing data first $this->data = null; // Obtain data via update or local cache $response = null; try { if($update) { $response = $this->Cloud->EC2->cache(-1)->describe_spot_instance_requests(); } else { $response = $this->Cloud->EC2->cache($this->Cloud->config['aws']['cache_seconds'].' seconds')->describe_spot_instance_requests(); } } catch (RequestCore_Exception $e) {} if(empty($response) || !$response->isOK() || !isset($response->{'body'})) { $this->Out->error('Unable to obtain cloud spot requests data'); return false; } $this->data = $response->{'body'}; if($last_out_has_new_line) { $this->Out->msg(' - done'); } else { $this->Out->msg(' - done',false); } } // Parse the response into a slightly more manageable/useful structure for us $spots = array(); if(isset($this->data->{'spotInstanceRequestSet'}->{'item'})) { // Reservations foreach($this->data->{'spotInstanceRequestSet'}->{'item'} as $spot) { // Extract the tags attached to this instance $instance_name = 'unknown'; $tags = array(); if(isset($spot->tagSet)) { foreach($spot->tagSet->item as $tag) { $tags[(string)$tag->{'key'}] = (string)$tag->{'value'}; } } $spots[(string) $spot->spotInstanceRequestId] = array( 'type' => (string) $spot->type, 'state' => (string) $spot->state, 'spotPrice' => (string) $spot->spotPrice, 'validFrom' => date('Y-m-d H:i:s',strtotime((string)$spot->validFrom)), 'validUntil' => date('Y-m-d H:i:s',strtotime((string)$spot->validUntil)), 'createTime' => date('Y-m-d H:i:s',strtotime((string)$spot->createTime)), 'productDescription' => (string) $spot->productDescription, 'tags' => $tags, ); } } //print_r($spots); //print_r($this->data); if(!empty($spot_id)) { if(isset($spots[$spot_id])) { return array( $spot_id => $spots[$spot_id] ); } return array(); } return $spots; }
public function cmd_spot() { $args = func_get_args(); $this->Out->debug(__METHOD__,$args); // Command setup if(isset($args[0]) && $args[0] == '__meta') { return array( 'command' => str_replace('cmd_','',__FUNCTION__), 'description' => 'Perform operations spot instance requests', 'sub_commands' => array( 'request' => array( '__usage' => '<spot request name or id> <price> [count]', '*' => array('*'=>array('[*]')), ), 'cancel' => array( '__usage' => '<spot request name or id>', '*', ), 'info' => array( '__usage' => '<spot request name or id> [defined]', '*' => array('[defined]'), ), 'list' => array( '__usage' => '[defined]', '[defined]', ), ) ); } // Validate the input arguments if(!$this->Shell->validateCommandArgs($args,__FUNCTION__)) { return false; } // Switch out to sub-command switch(strtolower($args[0])) { case 'request': if(isset($args[3])) { $this->Cloud->Spot->spotRequest($args[1],$args[2],$args[3]); } else { $this->Cloud->Spot->spotRequest($args[1],$args[2]); } break; case 'cancel': $this->Cloud->Spot->spotCancel($args[1]); break; case 'info': if(isset($args[1])) { $this->Cloud->Spot->spotInfo($args[1]); } break; case 'list': if(isset($args[1])) { $this->Cloud->Spot->spotList($args[1]); } else { $this->Cloud->Spot->spotList(); } break; default: $this->cmd_keypair(); } $this->Out->msg(); }