enviroblyd 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5dbb9c1de2225aad7c7211baf934798dd3a059ce4dabe7efeed4d96b1e804410
4
- data.tar.gz: c5eb8ba3ed2880049eb6094c30cdfb8a2514f5c22ba770f5a646027f9368ae7f
3
+ metadata.gz: 05071a7be6ad5145537f06b8466841984969e4c89759ea929ee0f1a28a6457cf
4
+ data.tar.gz: 79c5c57647395378dddd409ae90075e888e7e1999c997efd1c1e736b6a871fbb
5
5
  SHA512:
6
- metadata.gz: fbb457cd2d63bd5565c1b9ea0ceb96de79ad4def5e4674d691595cbee5706da25b339d96059f20e0779f77d76368688d16d3fe64c3a56eae5a8ace9d1ef2add0
7
- data.tar.gz: 2ed04fd30d0522315c2e56fd0a03010eb801c78bc2c17175ad1bc3b744e743dbe105486a1cc465a4de731a6099ced61bb18ada8696e477542f4aff2f4ed58f07
6
+ metadata.gz: 54cdd680ffb67c14da0795fee35ef925e44795fc91876917377b8c7be8e6719b4ecb6c8cb826ad3d941d6856680a7aff6700f7a0de284ec0847e026bc60e1acf
7
+ data.tar.gz: a71d5071c3bb1001f6f35ef5603a617b88aec4d1a54c338945afd1df43e6a764ce441b2324cc3a932f2b97df5ee5947221136ad86694bd7bae78922b10a5bd9c
data/bin/enviroblyctl ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "enviroblyd"
5
+
6
+ Enviroblyd::Cli::Main.start(ARGV)
data/bin/enviroblyd CHANGED
@@ -3,4 +3,4 @@
3
3
 
4
4
  require "enviroblyd"
5
5
 
6
- Enviroblyd::Cli::Main.start(ARGV)
6
+ Enviroblyd::Daemon.start
@@ -1,100 +1,8 @@
1
1
  # frozen_string_literal: true
2
- require "net/http"
3
- require "uri"
4
- require "open3"
5
- require "fileutils"
6
- require "pathname"
7
2
 
8
3
  class Enviroblyd::Cli::Main < Enviroblyd::Base
9
4
  desc "version", "Show version"
10
5
  def version
11
6
  puts Enviroblyd::VERSION
12
7
  end
13
-
14
- TOKEN_TTL_SECONDS = 30
15
- IMDS_HOST = ENV.fetch("ENVIROBLYD_IMDS_HOST", "169.254.169.254")
16
- API_HOST = ENV.fetch("ENVIROBLYD_API_HOST", "envirobly.com")
17
- WORKING_DIR = Pathname.new ENV.fetch("ENVIROBLYD_WORKING_DIR", "/var/envirobly/daemon")
18
- INITIALIZED_FILE = WORKING_DIR.join "initialized"
19
- desc "boot", "Start the daemon"
20
- def boot
21
- # @token = http("http://#{IMDS_HOST}/latest/api/token",
22
- # type: Net::HTTP::Put, headers: { "X-aws-ec2-metadata-token-ttl-seconds" => TOKEN_TTL_SECONDS.to_s }).
23
- # body.chomp("")
24
- # puts "token: #{@token} ."
25
- # instance_id = http("http://#{IMDS_HOST}/latest/meta-data/instance-id",
26
- # headers: { "X-aws-ec2-metadata-token" => @token }).
27
- # body.chomp("")
28
- # puts "instance_id: #{instance_id} ."
29
- #
30
- # response = http("https://#{API_HOST}/api/v1/boots/#{instance_id}", retry_interval: 3, retries: 5, backoff: :exponential)
31
- # puts "/api/v1/boots response code: #{response.code}"
32
-
33
- if File.exist?(INITIALIZED_FILE)
34
- puts "Skipping initialization because #{INITIALIZED_FILE} exists."
35
- else
36
- init_url = ENV.fetch "ENVIROBLYD_INIT_URL"
37
- puts "Init URL: #{init_url}"
38
- response = http(init_url, type: Net::HTTP::Put, retry_interval: 3, retries: 10, backoff: :exponential)
39
- puts "Init response code: #{response.code}"
40
-
41
- if response.code.to_i == 200
42
- FileUtils.mkdir_p WORKING_DIR
43
- File.write INITIALIZED_FILE, init_url
44
- end
45
- end
46
- end
47
-
48
- private
49
- def http(url, type: Net::HTTP::Get, headers: {}, retry_interval: 2, retries: 30, backoff: false, tries: 1)
50
- if retries <= tries
51
- $stderr.puts "Retried #{tries} times. Aborting."
52
- exit 1
53
- end
54
-
55
- uri = URI(url)
56
- http = Net::HTTP.new uri.host, uri.port
57
- http.use_ssl = true if uri.scheme == "https"
58
- http.open_timeout = 5
59
- http.read_timeout = 5
60
-
61
- request = type.new(uri, default_headers.merge(headers))
62
- # request.content_type = CONTENT_TYPE
63
-
64
- yield request if block_given?
65
-
66
- response =
67
- begin
68
- http.request(request)
69
- rescue
70
- :retry
71
- end
72
-
73
- # https://developers.cloudflare.com/support/troubleshooting/cloudflare-errors/troubleshooting-cloudflare-1xxx-errors/
74
- if response == :retry || (500..599).include?(response.code.to_i)
75
- sleep_time = (backoff == :exponential) ? (retry_interval * tries) : retry_interval
76
- $stderr.puts "Retry #{uri} in #{sleep_time}s"
77
- sleep sleep_time
78
- http(url, type:, retry_interval:, retries:, backoff:, tries: (tries + 1))
79
- else
80
- response
81
- end
82
- end
83
-
84
- RUN_TIMEOUT = "5m"
85
- def run(script)
86
- @stdout = @stderr = @exit_code = nil
87
- Open3.popen3("timeout #{RUN_TIMEOUT} /bin/bash") do |stdin, stdout, stderr, thread|
88
- stdin.puts script
89
- stdin.close
90
- @stdout = stdout.read
91
- @stderr = stderr.read
92
- @exit_code = thread.value.exitstatus
93
- end
94
- end
95
-
96
- USER_AGENT = "enviroblyd #{Enviroblyd::VERSION}"
97
- def default_headers
98
- { "User-Agent" => USER_AGENT }
99
- end
100
8
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+
5
+ class Enviroblyd::Command
6
+ DEFAULT_TIMEOUT_SECONDS = 5 * 60
7
+ DEFAULT_RUNTIME = "/bin/bash"
8
+
9
+ def initialize(params)
10
+ @web = Enviroblyd::Web.new
11
+ @url = params.fetch "url"
12
+ @script = params.fetch "script"
13
+ @runtime = params.fetch "runtime", DEFAULT_RUNTIME
14
+ @timeout = params.fetch "timeout", DEFAULT_TIMEOUT_SECONDS
15
+ @stdout = @stderr = @exit_code = nil
16
+ end
17
+
18
+ def run
19
+ puts "Command #{@url} starting"
20
+
21
+ Open3.popen3("timeout #{@timeout} #{@runtime}") do |stdin, stdout, stderr, thread|
22
+ stdin.puts @script
23
+ stdin.close
24
+ @stdout = stdout.read
25
+ @stderr = stderr.read
26
+ @exit_code = thread.value.exitstatus
27
+ end
28
+
29
+ puts "Command #{@url} exited with #{@exit_code}"
30
+ $stdout.flush
31
+
32
+ @web.http(@url, type: Net::HTTP::Put, params: to_complete_params)
33
+ end
34
+
35
+ private
36
+ def to_complete_params
37
+ {
38
+ command: {
39
+ stdout: @stdout,
40
+ stderr: @stderr,
41
+ exit_code: @exit_code
42
+ }
43
+ }
44
+ end
45
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+ require "json"
5
+
6
+ class Enviroblyd::Daemon
7
+ MAX_MESSAGE_SIZE = 6000 # bytes
8
+ LISTEN_PORT = ENV.fetch("ENVIROBLYD_PORT", 63106).to_i
9
+
10
+ def self.start
11
+ web = Enviroblyd::Web.new
12
+ web.register
13
+
14
+ daemon = new
15
+ daemon.listen
16
+ end
17
+
18
+ def listen
19
+ server = TCPServer.new LISTEN_PORT
20
+ puts "Listening on port #{LISTEN_PORT}"
21
+
22
+ loop do
23
+ Thread.start(server.accept) do |client|
24
+ message = client.recv(MAX_MESSAGE_SIZE)
25
+
26
+ params =
27
+ begin
28
+ JSON.parse message
29
+ rescue
30
+ nil
31
+ end
32
+
33
+ if params.nil?
34
+ client.puts "Error parsing JSON"
35
+ else
36
+ puts "Received valid JSON:"
37
+ puts params
38
+ client.puts "OK"
39
+ end
40
+
41
+ # TODO: Handle Broken pipe (Errno::EPIPE) (client closing connection before we write back)
42
+ client.close
43
+
44
+ Thread.new do
45
+ Enviroblyd::Command.new(params).run
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Enviroblyd
4
- VERSION = "0.3.1"
4
+ VERSION = "0.4.1"
5
5
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "uri"
5
+ require "open3"
6
+ require "fileutils"
7
+ require "pathname"
8
+ require "json"
9
+
10
+ class Enviroblyd::Web
11
+ USER_AGENT = "enviroblyd #{Enviroblyd::VERSION}"
12
+ CONTENT_TYPE = "application/json"
13
+ # TOKEN_TTL_SECONDS = 30
14
+ # IMDS_HOST = ENV.fetch("ENVIROBLYD_IMDS_HOST", "169.254.169.254")
15
+ API_HOST = ENV.fetch("ENVIROBLYD_API_HOST", "envirobly.com")
16
+ WORKING_DIR = Pathname.new ENV.fetch("ENVIROBLYD_WORKING_DIR", "/var/envirobly/daemon")
17
+ INITIALIZED_FILE = WORKING_DIR.join "initialized"
18
+
19
+ def register
20
+ if File.exist?(INITIALIZED_FILE)
21
+ puts "Skipping initialization because #{INITIALIZED_FILE} exists."
22
+ else
23
+ init_url = ENV.fetch "ENVIROBLYD_INIT_URL"
24
+ puts "Init URL: #{init_url}"
25
+ response = http(init_url, type: Net::HTTP::Put, retry_interval: 3, retries: 10, backoff: :exponential)
26
+ puts "Init response code: #{response.code}"
27
+
28
+ if response.code.to_i == 200
29
+ FileUtils.mkdir_p WORKING_DIR
30
+ File.write INITIALIZED_FILE, init_url
31
+ end
32
+ end
33
+ end
34
+
35
+ def http(url, type: Net::HTTP::Get, headers: {}, retry_interval: 2, retries: 30, backoff: false, tries: 1, params: nil)
36
+ if retries <= tries
37
+ $stderr.puts "Retried #{tries} times. Aborting."
38
+ exit 1
39
+ end
40
+
41
+ uri = URI(url)
42
+ http = Net::HTTP.new uri.host, uri.port
43
+ http.use_ssl = true if uri.scheme == "https"
44
+ http.open_timeout = 5
45
+ http.read_timeout = 5
46
+
47
+ request = type.new(uri, default_headers.merge(headers))
48
+ request.content_type = CONTENT_TYPE
49
+
50
+ unless params.nil?
51
+ request.body = JSON.dump params
52
+ end
53
+
54
+ response =
55
+ begin
56
+ http.request(request)
57
+ rescue
58
+ :retry
59
+ end
60
+
61
+ # https://developers.cloudflare.com/support/troubleshooting/cloudflare-errors/troubleshooting-cloudflare-1xxx-errors/
62
+ if response == :retry || (500..599).include?(response.code.to_i)
63
+ sleep_time = (backoff == :exponential) ? (retry_interval * tries) : retry_interval
64
+ $stderr.puts "Retry #{uri} in #{sleep_time}s"
65
+ sleep sleep_time
66
+ http(url, type:, retry_interval:, retries:, backoff:, tries: (tries + 1))
67
+ else
68
+ response
69
+ end
70
+ end
71
+
72
+ private
73
+ def default_headers
74
+ { "User-Agent" => USER_AGENT }
75
+ end
76
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enviroblyd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Starsi
@@ -55,16 +55,21 @@ dependencies:
55
55
  description:
56
56
  email: klevo@klevo.sk
57
57
  executables:
58
+ - enviroblyctl
58
59
  - enviroblyd
59
60
  extensions: []
60
61
  extra_rdoc_files: []
61
62
  files:
62
63
  - LICENSE
64
+ - bin/enviroblyctl
63
65
  - bin/enviroblyd
64
66
  - lib/enviroblyd.rb
65
67
  - lib/enviroblyd/base.rb
66
68
  - lib/enviroblyd/cli/main.rb
69
+ - lib/enviroblyd/command.rb
70
+ - lib/enviroblyd/daemon.rb
67
71
  - lib/enviroblyd/version.rb
72
+ - lib/enviroblyd/web.rb
68
73
  homepage: https://github.com/envirobly/enviroblyd
69
74
  licenses:
70
75
  - MIT