class Chef::Resource::HabitatService

Public Instance Methods

get_binding_mode(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 269
def get_binding_mode(service_details)
  service_details["binding_mode"].to_sym
rescue
  Chef::Log.debug("Binding mode for #{service_name} not found on Supervisor API")
  "strict"
end
get_binds(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 262
def get_binds(service_details)
  service_details["binds"]
rescue
  Chef::Log.debug("Update Strategy for #{service_name} not found on Supervisor API")
  []
end
get_builder_url(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 248
def get_builder_url(service_details)
  service_details["bldr_url"]
rescue
  Chef::Log.debug("Habitat Builder URL for #{service_name} not found on Supervisor API")
  "https://bldr.habitat.sh"
end
get_channel(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 255
def get_channel(service_details)
  service_details["channel"].to_sym
rescue
  Chef::Log.debug("Channel for #{service_name} not found on Supervisor API")
  "stable"
end
get_health_check_interval(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 290
def get_health_check_interval(service_details)
  service_details["health_check_interval"]["secs"]
rescue
  Chef::Log.debug("Health Check Interval for #{service_name} not found on Supervisor API")
  30
end
get_service_details(svc_name) click to toggle source

This method is defined here otherwise it isn’t usable in the ‘load_current_value` method.

It performs a check with TCPSocket to ensure that the HTTP API is available first. If it cannot connect, it assumes that the service is not running. It then attempts to reach the ‘/services` path of the API to get a list of services. If this fails for some reason, then it assumes the service is not running.

Finally, it walks the services returned by the API to look for the service we’re configuring. If it is “Up”, then we know the service is running and fully operational according to Habitat. This is wrapped in a begin/rescue block because if the service isn’t present and ‘sup_for_service_name` will be nil and we will get a NoMethodError.

# File lib/chef/resource/habitat_service.rb, line 180
def get_service_details(svc_name)
  http_uri = "http://#{remote_sup_http}"

  begin
    TCPSocket.new(URI(http_uri).host, URI(http_uri).port).close
  rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
    Chef::Log.debug("Could not connect to #{http_uri} to retrieve status for #{service_name}")
    return false
  end

  begin
    headers = {}
    headers["Authorization"] = "Bearer #{gateway_auth_token}" if property_is_set?(:gateway_auth_token)
    svcs = Chef::HTTP::SimpleJSON.new(http_uri).get("/services", headers)
  rescue
    Chef::Log.debug("Could not connect to #{http_uri}/services to retrieve status for #{service_name}")
    return false
  end

  origin, name, _version, _release = svc_name.split("/")
  svcs.find do |s|
    s["pkg"]["origin"] == origin && s["pkg"]["name"] == name
  end
end
get_service_group(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 276
def get_service_group(service_details)
  service_details["service_group"].split(".").last
rescue
  Chef::Log.debug("Service Group for #{service_name} not found on Supervisor API")
  "default"
end
get_shutdown_timeout(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 283
def get_shutdown_timeout(service_details)
  service_details["pkg"]["shutdown_timeout"]
rescue
  Chef::Log.debug("Shutdown Timeout for #{service_name} not found on Supervisor API")
  8
end
get_spec_identifier(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 220
def get_spec_identifier(service_details)
  service_details["spec_ident"]["spec_identifier"]
rescue
  Chef::Log.debug("#{service_name} not found on the Habitat supervisor")
  nil
end
get_topology(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 241
def get_topology(service_details)
  service_details["topology"].to_sym
rescue
  Chef::Log.debug("Topology for #{service_name} not found on Supervisor API")
  "standalone"
end
get_update_condition(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 234
def get_update_condition(service_details)
  service_details["update_condition"].to_sym
rescue
  Chef::Log.debug("Update condition #{service_name} not found on Supervisor API")
  "latest"
end
get_update_strategy(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 227
def get_update_strategy(service_details)
  service_details["update_strategy"].to_sym
rescue
  Chef::Log.debug("Update Strategy for #{service_name} not found on Supervisor API")
  "none"
end
service_loaded?(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 212
def service_loaded?(service_details)
  if service_details
    true
  else
    false
  end
end
service_up?(service_details) click to toggle source
# File lib/chef/resource/habitat_service.rb, line 205
def service_up?(service_details)
  service_details["process"]["state"] == "up"
rescue
  Chef::Log.debug("#{service_name} not found on the Habitat supervisor")
  false
end
svc_options() click to toggle source
# File lib/chef/resource/habitat_service.rb, line 387
def svc_options
  opts = []

  # certain options are only valid for specific `hab svc` subcommands.
  case action
  when :load
    opts.push(*new_resource.bind.map { |b| "--bind #{b}" }) if new_resource.bind
    opts << "--binding-mode #{new_resource.binding_mode}"
    opts << "--url #{new_resource.bldr_url}" if new_resource.bldr_url
    opts << "--channel #{new_resource.channel}" if new_resource.channel
    opts << "--group #{new_resource.service_group}" if new_resource.service_group
    opts << "--strategy #{new_resource.strategy}" if new_resource.strategy
    opts << "--update-condition #{new_resource.update_condition}" if new_resource.update_condition
    opts << "--topology #{new_resource.topology}" if new_resource.topology
    opts << "--health-check-interval #{new_resource.health_check_interval}" if new_resource.health_check_interval
    opts << "--shutdown-timeout #{new_resource.shutdown_timeout}" if new_resource.shutdown_timeout
  when :unload, :stop
    opts << "--shutdown-timeout #{new_resource.shutdown_timeout}" if new_resource.shutdown_timeout
  end

  opts << "--remote-sup #{new_resource.remote_sup}" if new_resource.remote_sup

  opts.map(&:split).flatten.compact
end
wait_for_service_stopped() click to toggle source
# File lib/chef/resource/habitat_service.rb, line 430
def wait_for_service_stopped
  ruby_block "wait-for-service-stopped" do
    block do
      raise "#{new_resource.service_name} still running" if service_up?(get_service_details(new_resource.service_name))
    end
    retries get_shutdown_timeout(new_resource.service_name) + 1
    retry_delay 1

    ruby_block "update current_resource" do
      block do
        current_resource.running = service_up?(get_service_details(new_resource.service_name))
      end
      action :nothing
      subscribes :run, "ruby_block[wait-for-service-stopped]", :immediately
    end
  end
end
wait_for_service_unloaded() click to toggle source
# File lib/chef/resource/habitat_service.rb, line 412
def wait_for_service_unloaded
  ruby_block "wait-for-service-unloaded" do
    block do
      raise "#{new_resource.service_name} still loaded" if service_loaded?(get_service_details(new_resource.service_name))
    end
    retries get_shutdown_timeout(new_resource.service_name) + 1
    retry_delay 1
  end

  ruby_block "update current_resource" do
    block do
      current_resource.loaded = service_loaded?(get_service_details(new_resource.service_name))
    end
    action :nothing
    subscribes :run, "ruby_block[wait-for-service-unloaded]", :immediately
  end
end