Module: Fly::Machines

Defined in:
lib/fly.io-rails/machines.rb

Overview

Thin wrapper over fly.io/docs/reference/machines/

*** WARNING ***

No validation or escaping is done by this code. It is assuming that the caller is trusted and does pass through unsanitized user input.

Constant Summary collapse

@@api_token =
ENV['FLY_API_TOKEN']
@@fly_api_hostname =
nil

Class Method Summary collapse

Class Method Details

.api(path, host = nil, &make_request) ⇒ Object

common processing for all APIs



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/fly.io-rails/machines.rb', line 173

def self.api(path, host=nil, &make_request)
  host ||= "http://#{fly_api_hostname}"
  uri = URI.join(host, path)
  http = Net::HTTP.new(uri.host, uri.port)
  http.set_debug_output $stderr if ENV['TRACE'] 
  http.use_ssl = true if uri.instance_of? URI::HTTPS

  request = make_request.call(uri.request_uri)

  @@api_token ||= `flyctl auth token`.chomp
  headers = {
    "Authorization" => "Bearer #{@@api_token}",
    "Content-Type" => "application/json",
    "Accept" => "application/json"
  }
  headers.each {|header, value| request[header] = value}

  response = http.request(request)

  if response.is_a? Net::HTTPSuccess
    JSON.parse response.body, symbolize_names: true
  else
    body = response.body
    begin
      error = JSON.parse(body)
    rescue
      error = {body: body}
    end

    error[:status] = response.code
    error[:message] = response.message

    error
  end
end

.create_and_start_machine(app, options) ⇒ Object

create_and_start_machine ‘user-functions’, name: ‘quirky_machine’, config:

image: 'flyio/fastify-functions',
env: {'APP_ENV' => 'production',
services: [
  {
    ports: [
      443, handlers: ['tls', 'http'],
      80, handlers: ['http']
    ],
    protocol: 'tcp',
    internal_protocol: 'tcp',
  }
]

}



97
98
99
# File 'lib/fly.io-rails/machines.rb', line 97

def self.create_and_start_machine app, options
  post "/v1/apps/#{app}/machines", options
end

.create_fly_application(options) ⇒ Object

create_fly_application app_name: ‘user-functions’, org_slug: ‘personal’



74
75
76
# File 'lib/fly.io-rails/machines.rb', line 74

def self.create_fly_application options
  post '/v1/apps', options
end

.delete(path) ⇒ Object

generic delete



159
160
161
# File 'lib/fly.io-rails/machines.rb', line 159

def self.delete(path)
  api(path) {|uri| request = Net::HTTP::Delete.new(uri) }
end

.delete_application(app, force = false) ⇒ Object

delete_application ‘user-functions’



140
141
142
# File 'lib/fly.io-rails/machines.rb', line 140

def self.delete_application app, force=false
  delete "/v1/apps/#{app}?force=#{force}"
end

.delete_machine(app, machine) ⇒ Object

delete_machine machine ‘user-functions’, ‘73d8d46dbee589’



130
131
132
# File 'lib/fly.io-rails/machines.rb', line 130

def self.delete_machine app, machine
  delete "/v1/apps/#{app}/machines/#{machine}"
end

.fly_api_hostnameObject

determine fly api hostname. Returns nil if no proxy is running



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/fly.io-rails/machines.rb', line 17

def self.fly_api_hostname
  return @@fly_api_hostname if @@fly_api_hostname

  Net::HTTP.get URI('http://_api.internal:4280')
  @@fly_api_hostname = '_api.internal:4280'
rescue
  begin
    Net::HTTP.get URI('http://127.0.0.1:4280')
    @@fly_api_hostname = '127.0.0.1:4280'
  rescue
    nil
  end
end

.fly_api_hostname!Object

determine fly api hostname. Starts proxy if necessary



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/fly.io-rails/machines.rb', line 50

def self.fly_api_hostname!
  hostname = fly_api_hostname
  return hostname if hostname

  pid = fork { exec "flyctl machines api-proxy --org #{org}" }
  at_exit { Process.kill "INT", pid }

  # wait up to 12.7 seconds for the proxy to start
  wait = 0.1
  6.times do
    sleep wait
    begin
      Net::HTTP.get URI('http://127.0.0.1:4280')
      @@fly_api_hostname = '127.0.0.1:4280'
      break
    rescue
      wait *= 2
    end
  end

  @@fly_api_hostname
end

.get(path) ⇒ Object

generic get



145
146
147
# File 'lib/fly.io-rails/machines.rb', line 145

def self.get(path)
  api(path) {|uri| request = Net::HTTP::Get.new(uri) }
end

.get_a_machine(app, machine) ⇒ Object

get_a_machine machine ‘user-functions’, ‘73d8d46dbee589’



107
108
109
# File 'lib/fly.io-rails/machines.rb', line 107

def self.get_a_machine app, machine
  get "/v1/apps/#{app}/machines/#{machine}"
end

.get_application_details(app) ⇒ Object

get_application_details ‘user-functions’



79
80
81
# File 'lib/fly.io-rails/machines.rb', line 79

def self.get_application_details app
  get "/v1/apps/#{app}"
end

.graphql(query) ⇒ Object



164
165
166
167
168
169
170
# File 'lib/fly.io-rails/machines.rb', line 164

def self.graphql(query)
  api('/graphql', 'https://api.fly.io/') do |path|
    request = Net::HTTP::Post.new(path)
    request.body = { query: query }.to_json
    request
  end
end

.list_machines(app, machine) ⇒ Object

list_machines machine ‘user-functions’



135
136
137
# File 'lib/fly.io-rails/machines.rb', line 135

def self.list_machines app, machine
  get "/v1/apps/#{app}/machines"
end

.orgObject

determine application’s organization



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/fly.io-rails/machines.rb', line 32

def self.org
  org = 'personal'

  if File.exist? 'fly.toml'
    require 'toml'
    app = TOML.load_file('fly.toml')['app']

    apps = JSON.parse(`flyctl list apps --json`) rescue []

    apps.each do |info|
      org = info['Organization'] if info['ID'] == app
    end
  end

  org
end

.post(path, hash = nil) ⇒ Object

generic post



150
151
152
153
154
155
156
# File 'lib/fly.io-rails/machines.rb', line 150

def self.post(path, hash=nil)
  api(path) do |uri|
    request = Net::HTTP::Post.new(uri)
    request.body = hash.to_json if hash
    request
  end
end

.start_machine(app, machine) ⇒ Object

start_machine machine ‘user-functions’, ‘73d8d46dbee589’



125
126
127
# File 'lib/fly.io-rails/machines.rb', line 125

def self.start_machine app, machine
  post "/v1/apps/#{app}/machines/#{machine}/stop"
end

.stop_machine(app, machine) ⇒ Object

stop_machine machine ‘user-functions’, ‘73d8d46dbee589’



120
121
122
# File 'lib/fly.io-rails/machines.rb', line 120

def self.stop_machine app, machine
  post "/v1/apps/#{app}/machines/#{machine}/stop"
end

.update_a_machine(app, machine, options) ⇒ Object

update_a_machine ‘user-functions’, ‘73d8d46dbee589’, config: {

image: 'flyio/fastify-functions',
guest: { memory_mb: 512, cpus: 2 }

}



115
116
117
# File 'lib/fly.io-rails/machines.rb', line 115

def self.update_a_machine app, machine, options
  post "/v1/apps/#{app}/machines/#{machine}", options
end

.wait_for_machine(app, machine, options = {timeout:60, status: 'started'}) ⇒ Object

wait_for_machine ‘user-functions’, ‘73d8d46dbee589’



102
103
104
# File 'lib/fly.io-rails/machines.rb', line 102

def self.wait_for_machine app, machine, options = {timeout:60, status: 'started'}
  get "/v1/apps/#{app}/machines/#{machine}/wait?#{options.to_query}"
end