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_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
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/cloud_powers/self_awareness.rb', line 25 def boot_time begin ec2(Smash::CloudPowers::AwsStubs.node_stub) sqs(Smash::CloudPowers::AwsStubs.queue_stub) sns(Smash::CloudPowers::AwsStubs.broadcast_stub) kinesis(Smash::CloudPowers::AwsStubs.pipe_stub) @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 => e 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.
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 |
# File 'lib/cloud_powers/self_awareness.rb', line 42 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 => e 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!()
78 79 80 81 82 83 84 |
# File 'lib/cloud_powers/self_awareness.rb', line 78 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
90 91 92 |
# File 'lib/cloud_powers/self_awareness.rb', line 90 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
102 103 104 105 106 107 108 109 |
# File 'lib/cloud_powers/self_awareness.rb', line 102 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 blankStringif key is given
Example metadata_request
=> a Hash containing every key => value pair AWS provides
metadata_request('instance-id')
=> 'abc-1234'
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/cloud_powers/self_awareness.rb', line 128 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 require_relative '../stubs/aws_stubs' = 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.
153 154 155 |
# File 'lib/cloud_powers/self_awareness.rb', line 153 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
163 164 165 166 167 168 169 170 171 172 |
# File 'lib/cloud_powers/self_awareness.rb', line 163 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
180 181 182 183 184 185 186 187 188 |
# File 'lib/cloud_powers/self_awareness.rb', line 180 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 => e 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
199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/cloud_powers/self_awareness.rb', line 199 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
219 220 221 222 223 224 225 |
# File 'lib/cloud_powers/self_awareness.rb', line 219 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 |