faaso/src/daemon.cr

115 lines
2.7 KiB
Crystal
Raw Normal View History

2024-06-30 16:11:35 +00:00
require "crystar"
require "compress/gzip"
require "docr"
2024-06-30 14:55:46 +00:00
require "kemal-basic-auth"
2024-06-30 16:11:35 +00:00
require "kemal"
require "uuid"
2024-06-30 14:55:46 +00:00
# FIXME: make configurable
basic_auth "admin", "admin"
2024-06-30 21:05:02 +00:00
current_config = File.read("tinyproxy.conf")
# Get current proxy config
get "/proxy/" do
current_config
end
2024-06-29 23:48:03 +00:00
2024-06-30 16:11:35 +00:00
# Bump proxy config to current docker state, returns
# new proxy config
2024-06-30 21:05:02 +00:00
patch "/proxy/" do
Log.info { "Updating routing" }
# Get all the funkos, create routes for them all
docker_api = Docr::API.new(Docr::Client.new)
containers = docker_api.containers.list(all: true)
funkos = [] of String
containers.each { |container|
names = container.names.select &.starts_with? "/faaso-"
next if names.empty?
funkos << names[0][7..]
}
2024-06-29 23:48:03 +00:00
funkos.sort!
proxy_config = %(
Port 8888
Listen 0.0.0.0
Timeout 600
Allow 0.0.0.0/0
ReverseOnly Yes
ReverseMagic Yes
ReversePath "/admin/" "http://127.0.0.1:3000/"
) + funkos.map { |funko| %(ReversePath "/faaso/#{funko}/" "http://#{funko}:3000/") }.join("\n")
2024-06-29 23:48:03 +00:00
if current_config != proxy_config
File.open("tinyproxy.conf", "w") do |file|
file << proxy_config
end
# Reload config
Process.run(command: "/usr/bin/killall", args: ["-USR1", "tinyproxy"])
current_config = proxy_config
2024-06-29 23:38:34 +00:00
end
proxy_config
end
2024-06-30 18:38:51 +00:00
# Bring up the funko
get "/funko/:name/up/" do |env|
name = env.params.url["name"]
response = run_faaso(["up", name])
if response["exit_code"] != 0
halt env, status_code: 500, response: response.to_json
else
response.to_json
end
end
2024-06-30 16:11:35 +00:00
# Build image for funko received as "funko.tgz"
# TODO: This may take a while, consider using something like
# mosquito-cr/mosquito to make it a job queue
post "/funko/build/" do |env|
# Create place to build funko
tmp_dir = Path.new("tmp", UUID.random.to_s)
Dir.mkdir_p(tmp_dir) unless File.exists? tmp_dir
# Expand tarball in there
file = env.params.files["funko.tgz"].tempfile
Compress::Gzip::Reader.open(file) do |gzip|
Crystar::Reader.open(gzip) do |tar|
tar.each_entry do |entry|
File.open(Path.new(tmp_dir, entry.name), "w") do |dst|
IO.copy entry.io, dst
end
end
end
end
# Build the thing
2024-06-30 18:23:16 +00:00
response = run_faaso(["build", tmp_dir.to_s])
if response["exit_code"] != 0
halt env, status_code: 500, response: response.to_json
else
response.to_json
end
end
def run_faaso(args : Array(String))
2024-06-30 16:11:35 +00:00
stderr = IO::Memory.new
stdout = IO::Memory.new
status = Process.run(
command: "faaso",
2024-06-30 18:23:16 +00:00
args: args + ["-l"], # Always local in the server
2024-06-30 16:11:35 +00:00
output: stdout,
error: stderr,
)
2024-06-30 18:23:16 +00:00
{
2024-06-30 16:11:35 +00:00
"exit_code" => status.exit_code,
"stdout" => stdout.to_s,
"stderr" => stderr.to_s,
2024-06-30 18:23:16 +00:00
}
2024-06-30 16:11:35 +00:00
end
Kemal.run