Module: Smash::CloudPowers::SelfAwareness
- Includes:
- AwsResources
- Included in:
- Smash::CloudPowers, Node
- Defined in:
- lib/cloud_powers/self_awareness.rb
Instance Method Summary collapse
-
#boot_time ⇒ Object
Gets the instance time or the time it was called and as seconds from epoch.
-
#die! ⇒ Object
Send a status message on the status Pipe then terminates the instance.
-
#get_awareness! ⇒ Object
Get resource metadata, public host, boot time and task name and set them as instance variables.
-
#instance_id ⇒ Object
Assures there is always a valid instance id because many other Aws calls require it.
-
#instance_url ⇒ Object
Gets and sets the public hostname of the instance.
-
#metadata_request(key = '') ⇒ Object
Makes the http request to self/meta-data to get all the metadata keys or, if a key is given, the method makes the http request to get that particular key from the metadata.
-
#run_time ⇒ Object
Return the time since boot_time.
-
#send_frequent_status_updates(opts = {}) ⇒ Object
Send a message on a Pipe at an interval.
-
#status(id = @instance_id) ⇒ Object
Get the instance status.
-
#task_name(id = @instance_id) ⇒ Object
Check self-tags for ‘task’ and act as an attr_accessor.
-
#time_is_up? ⇒ Boolean
This method will return true if: * The run time is more than 5 minutes and * The run time is 5 minutes from the hour mark from when the instance started and will return false otherwise.
Methods included from Helper
attr_map!, available_resources, called_from, create_logger, deep_modify_keys_with, format_error_message, log_file, logger, modify_keys_with, smart_retry, task_exist?, task_home, task_path, task_require_path, to_camel, to_hyph, to_i_var, to_pascal, to_ruby_file_name, to_snake, update_message_body, valid_json?, valid_url?
Methods included from Smash::CloudPowers::Synapse::Pipe
create_stream, flow_from_pipe, flow_to_pipe, from_pipe, message_body_collection, pipe_message_body, pipe_to, stream_config, stream_exists?, stream_status
Methods included from Zenv
env_vars, file_tree_search, i_vars, project_root, project_root=, system_vars, zfind
Methods included from AwsResources
#ec2, #image, #kinesis, #region, #s3, #sns, #sqs
Methods included from Auth
Methods included from Smash::CloudPowers::Synapse::Queue
board_name, build_queue, create_queue!, delete_queue_message, get_queue_message_count, pluck_queue_message, poll, queue_exists?, queue_poller, queue_search, send_queue_message
Instance Method Details
#boot_time ⇒ Object
Gets the instance time or the time it was called and as seconds from epoch
Returns Integer
Notes
-
TODO: use time codes
26 27 28 29 30 31 32 33 34 35 |
# File 'lib/cloud_powers/self_awareness.rb', line 26 def boot_time begin @boot_time ||= ec2.describe_instances(dry_run: zfind(:testing), instance_ids:[instance_id]). reservations[0].instances[0].launch_time.to_i rescue Aws::EC2::Errors::DryRunOperation logger.info "dry run for testing: #{e}" @boot_time ||= Time.now.to_i # comment the code below for development mode end end |
#die! ⇒ Object
Send a status message on the status Pipe then terminates the instance.
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 |
# File 'lib/cloud_powers/self_awareness.rb', line 38 def die! Thread.kill(@status_thread) unless @status_thread.nil? # blame = errors.sort_by(&:reverse).last.first logger.info("The cause for the shutdown is TODO: fix SmashErrors") pipe_to(:status_stream) do { instanceID: @instance_id, type: 'status-update', content: 'dying' # extraInfo: blame } end [:count, :wip].each do |queue| (queue, max_number_of_messages: 1) end send_logs_to_s3 begin ec2.terminate_instances(dry_run: zfind('testing'), ids: [@instance_id]) rescue Aws::EC2::Error::DryRunOperation logger.info "dry run testing in die! #{(e)}" @instance_id end end |
#get_awareness! ⇒ Object
Get resource metadata, public host, boot time and task name and set them as instance variables
Returns Array of values, each from a separate key, set in the order in the Array
Notes
-
See #metadata_request()
-
See #attr_map!()
74 75 76 77 78 79 80 |
# File 'lib/cloud_powers/self_awareness.rb', line 74 def get_awareness! keys = attr_map!(keys) { |key| (key) } boot_time # gets and sets @boot_time task_name # gets and sets @task_name instance_url # gets and sets @instance_url end |
#instance_id ⇒ Object
Assures there is always a valid instance id because many other Aws calls require it
Returns String
86 87 88 |
# File 'lib/cloud_powers/self_awareness.rb', line 86 def instance_id @instance_id ||= ('instance_id') end |
#instance_url ⇒ Object
Gets and sets the public hostname of the instance
Returns String - the Public Hostname for this instance
Notes
-
When this is being called from somewhere other than an Aws instance, a hardcoded example URL is returned because of the way instance metadata is retrieved
98 99 100 101 102 103 104 105 |
# File 'lib/cloud_powers/self_awareness.rb', line 98 def instance_url @instance_url ||= unless zfind('TESTING') hostname_uri = 'http://169.254.169.254/latest/meta-data/public-hostname' HTTParty.get(hostname_uri).parsed_response else 'http://ec2-000-0-000-00.compute-0.amazonaws.com' end end |
#metadata_request(key = '') ⇒ Object
Makes the http request to self/meta-data to get all the metadata keys or, if a key is given, the method makes the http request to get that particular key from the metadata
Parameters
-
key
String(optional) (default is ”) - the key for the metadata information you want from this instance.
Returns
-
Arrayif key is blank -
Stringif key is given
Example
# => a +Hash+ containing every key => value pair AWS provides
('instance-id')
# => 'abc-1234'
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/cloud_powers/self_awareness.rb', line 124 def (key = '') key = to_hyph(key) begin unless zfind('TESTING') = "http://169.254.169.254/latest/meta-data/#{key}" HTTParty.get().parsed_response.split("\n") else = Smash::CloudPowers::AwsStubs. key.empty? ? .keys : [to_hyph(key)] end rescue Exception => e logger.fatal e end end |
#run_time ⇒ Object
Return the time since boot_time
Returns Integer
Notes
-
TODO: refactor to use valid time stamps for better tracking.
-
reason -> separate regions or OSs etc.
148 149 150 |
# File 'lib/cloud_powers/self_awareness.rb', line 148 def run_time Time.now.to_i - boot_time end |
#send_frequent_status_updates(opts = {}) ⇒ Object
Send a message on a Pipe at an interval
Parameters
-
opts
Hash(optional) -
:interval- how long to wait between sending updates
-
-
:stream_name- name of stream you want to use
-
158 159 160 161 162 163 164 165 166 167 |
# File 'lib/cloud_powers/self_awareness.rb', line 158 def send_frequent_status_updates(opts = {}) sleep_time = opts.delete(:interval) || 10 stream = opts.delete(:stream_name) while true = lambda { |o| (o.merge(content: status)) } logger.info "Send update to status board #{.call(opts)}" pipe_to(stream || :status_stream) { .call(opts) } sleep sleep_time end end |
#status(id = @instance_id) ⇒ Object
Get the instance status.
Parameters
-
id
String(optional) (default is @instance_id)
Returns String
175 176 177 178 179 180 181 182 183 |
# File 'lib/cloud_powers/self_awareness.rb', line 175 def status(id = @instance_id) begin ec2.describe_instances(dry_run: zfind('TESTING'), instance_ids: [id]). reservations[0].instances[0].state.name rescue Aws::EC2::Errors::DryRunOperation logger.info "Dry run flag set for testing: #{e}" 'testing' end end |
#task_name(id = @instance_id) ⇒ Object
Check self-tags for ‘task’ and act as an attr_accessor. A different node’s tag’s can be checked for a task by passing that instance’s id as a parameter
Parameters
-
id
String(optional) (default is @instance_id) - instance you want a tag from
Returns String
194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/cloud_powers/self_awareness.rb', line 194 def task_name(id = @instance_id) # get @task_name return @task_name unless @task_name.nil? # set @task_name # TODO: get all tasks instead of just the first resp = ec2.describe_instances(instance_ids: [id].flatten).reservations.first return @task_name = nil if resp.nil? @task_name = resp.instances[0]..select do |t| t.value if t.key == 'taskType' end.first end |
#time_is_up? ⇒ Boolean
This method will return true if:
-
The run time is more than 5 minutes
and
-
The run time is 5 minutes from the hour mark from when the instance started
and will return false otherwise
Returns Boolean
214 215 216 217 218 219 220 |
# File 'lib/cloud_powers/self_awareness.rb', line 214 def time_is_up? an_hours_time = 60 * 60 five_minutes_time = 60 * 5 return false if run_time < five_minutes_time run_time % an_hours_time < five_minutes_time end |