enviroblyd 0.3.1 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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