'Error executing ruby script in docker environment
I have a script that is supposed to just check when my elasticsearch instance/container is up and running. But there appears to be some issue with the calls, as I get the error:
TypeError: Failed to open TCP connection to : (no implicit conversion of nil into String)
Here is the ruby code:
class AwaitEs
def self.call(uri)
AwaitEs.new(uri).wait
def initialize(uri)
@uri = URI.parse("#{uri}/_cluster/health")
def wait
status = get_status
until VALID_STATUS.include? status
puts 'Still waiting ...'
sleep 5
status = get_status
def get_status
HEADER = {'Content-Type' => 'application/json' }.freeze
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri, HEADER)
begin
res = http.request(request)
rescue Errno:ECONNREFUSED
return 'red'
end
result = JSON.parse(response.body)
result['status']
private
attr_reader :uri
VALID_STATUS = %w[yellow green].freeze
AwaitEs.call ARGV[0]
The error occurs on the line res = http.request(request). It appears that there is no host or port information. But when I check uri.host=elasticsearch and uri.port=9200, where elasticsearch is the name of the docker service for ES. When I change the host to localhost, the error disappears, but instead I get Connection refused instead (because the waiter docker does not see the elasticsearch docker on localhost.
The docker container calls the ruby script using a shell script named start.sh
#!/bin/sh
for file in `ls ./??_*.rb`; do
ruby $file `http://elasticsearch:9200`
done
The docker-compose.yml:
volumes:
es_data: {}
services:
elasticsearch:
image: elasticsearch:5.4.3
ports: ['9200:9200', '9300:9300']
volumes:
- es_data:/usr/share/elsticsearch/data
waiter:
build:
context: ./waiter/
Finally the dockerfile for waiter:
FROM jruby:9.1.15-alpine
ADD ./ /app/
WORKDIR /app
CMD bash -c "./start.sh"
When I run this, I get the error:
Solution 1:[1]
You need to reference uri correctly in the get_status method as an instance variable or pass it along with the get_status method.
Change the following:
def get_status
HEADER = {'Content-Type' => 'application/json' }.freeze
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri, HEADER)
begin
res = http.request(request)
rescue Errno:ECONNREFUSED
return 'red'
end
result = JSON.parse(response.body)
result['status']
To use an instance variable @uri, like this:
def get_status
HEADER = {'Content-Type' => 'application/json' }.freeze
http = Net::HTTP.new(@uri.host, @uri.port)
request = Net::HTTP::Get.new(@uri.request_uri, HEADER)
begin
res = http.request(request)
rescue Errno:ECONNREFUSED
return 'red'
end
result = JSON.parse(response.body)
result['status']
Or you can pass it along as a method parameter. In that case, change this:
def wait
status = get_status
until VALID_STATUS.include? status
puts 'Still waiting ...'
sleep 5
status = get_status
def get_status
HEADER = {'Content-Type' => 'application/json' }.freeze
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri, HEADER)
begin
res = http.request(request)
rescue Errno:ECONNREFUSED
return 'red'
end
result = JSON.parse(response.body)
result['status']
to this:
def wait
status = get_status(@uri)
until VALID_STATUS.include? status
puts 'Still waiting ...'
sleep 5
status = get_status(@uri)
def get_status(uri)
HEADER = {'Content-Type' => 'application/json' }.freeze
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri, HEADER)
begin
res = http.request(request)
rescue Errno:ECONNREFUSED
return 'red'
end
result = JSON.parse(response.body)
result['status']
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | DogEatDog |
