예제 #1
0
        /**
         * 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;
        }
예제 #2
0
        /**
         * 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;
        }
예제 #3
0
        /**
         * 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();
        }
예제 #4
0
        /**
         * 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;
        }
예제 #5
0
        /**
         * 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;
        }
예제 #6
0
        /**
         * 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;
        }
예제 #7
0
        /**
         * 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;
        }
예제 #8
0
        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();
        }