Compare commits

..

No commits in common. "6ca518ae321520471a8789ef900d24722dc44820" and "a4f722a1e08d2f483727472388afc23c9840172e" have entirely different histories.

10 changed files with 267 additions and 330 deletions

View File

@ -3,7 +3,7 @@ build: shard.yml $(wildcard src/**/*cr)
proxy: build proxy: build
docker build . -t faaso-proxy --no-cache docker build . -t faaso-proxy --no-cache
start-proxy: start-proxy:
docker run --name faaso_proxy --rm --network=faaso-net -v /var/run/docker.sock:/var/run/docker.sock -v secrets:/home/app/secrets -p 8888:8888 faaso-proxy docker run --network=faaso-net -v /var/run/docker.sock:/var/run/docker.sock -v secrets:/home/app/secrets -p 8888:8888 faaso-proxy
.PHONY: build proxy-image start-proxy .PHONY: build proxy-image start-proxy

View File

@ -1,14 +1,15 @@
<!DOCTYPE html>
<head> <head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css" /> <link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css" />
<script src="https://unpkg.com/htmx.org@2.0.0"></script> <script src="https://unpkg.com/htmx.org@2.0.0"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<body> <body>
<header class="container"> <script>
<h1>Your Funko Collection</h1> async function getFunkos() {
</header> const response = await fetch("funkos/");
<main class=container> funkos = await response.json();
console.log(funkos);
}
getFunkos();
</script>
<button hx-get="funkos/?format=html" hx-target="#funko-list">Update</button> <button hx-get="funkos/?format=html" hx-target="#funko-list">Update</button>
<table> <table>
<thead> <thead>
@ -20,6 +21,5 @@
<tbody id="funko-list"> <tbody id="funko-list">
</tbody> </tbody>
</thead> </thead>
</main>
</body> </body>
</head> </head>

View File

@ -1,37 +0,0 @@
require "docr"
require "kemal"
require "../funko.cr"
module Funko
extend self
get "/funkos/" do |env|
funkos = Funko.from_docker
funkos.sort! { |a, b| a.name <=> b.name }
result = [] of Hash(String, String)
funkos.each do |funko|
state = ""
case funko
when .running?
state = "running"
when .paused?
state = "paused"
else
state = "stopped"
end
result << {
"name" => funko.name,
"state" => state,
"status" => funko.status,
}
end
if env.params.query.fetch("format", "json") == "html"
render "src/views/funkos.ecr"
else
result.to_json
end
end
end

17
src/daemon/funkos.cr Normal file
View File

@ -0,0 +1,17 @@
require "docr"
require "kemal"
require "../funko.cr"
module Funkos
get "/funkos/" do |env|
funkos : Array(Funko) = Funko.from_docker
funkos.sort! { |a, b| a.name <=> b.name }
if env.params.query.fetch("format", "json") == "html"
render "src/views/funkos.ecr"
else
funkos.to_json
end
end
end

View File

@ -1,4 +1,4 @@
require "./funko.cr" require "./funkos.cr"
require "./proxyconf.cr" require "./proxyconf.cr"
require "./secrets.cr" require "./secrets.cr"
require "compress/gzip" require "compress/gzip"

View File

@ -1,10 +1,44 @@
require "kemal" require "kemal"
require "../secrets.cr"
module Secrets module Secrets
extend self SECRETS = Hash(String, String).new
SECRET_PATH = "./secrets/"
# TODO: sanitize all inputs # TODO: sanitize all inputs
# Store secrets in a tree of files
def self.update_secrets
# Save new secrets
SECRETS.map do |_name, value|
funko, name = _name.split("-", 2)
funko_dir = Path.new(SECRET_PATH, funko)
Dir.mkdir_p(funko_dir)
File.write(Path.new(funko_dir, name), value)
end
# Delete secrets not in the hash
Dir.glob(Path.new(SECRET_PATH, "*")).each do |funko_dir|
funko = File.basename(funko_dir)
Dir.glob(Path.new(funko_dir, "*")).each do |secret_file|
name = File.basename(secret_file)
unless SECRETS.has_key?("#{funko}-#{name}")
File.delete(secret_file)
end
end
end
end
# Load secrets from the disk
def self.load_secrets
Dir.glob(Path.new(SECRET_PATH, "*")).each do |funko_dir|
funko = File.basename(funko_dir)
Dir.glob(Path.new(funko_dir, "*")).each do |secret_file|
name = File.basename(secret_file)
value = File.read(secret_file)
SECRETS["#{funko}-#{name}"] = value
end
end
end
# Gets a secret in form {"name": "funko_name-secret_name", "value": "secret_value"} # Gets a secret in form {"name": "funko_name-secret_name", "value": "secret_value"}
post "/secrets/" do |env| post "/secrets/" do |env|
name = env.params.json["name"].as(String) name = env.params.json["name"].as(String)

View File

@ -38,7 +38,7 @@ module Faaso
end end
def run def run
funkos = Funko::Funko.from_paths(@arguments) funkos = Funko.from_paths(@arguments)
local = @options.@bool["local"] local = @options.@bool["local"]
if local if local
@ -120,7 +120,7 @@ module Faaso
end end
def run def run
funkos = Funko::Funko.from_names(@arguments) funkos = Funko.from_names(@arguments)
funkos.each do |funko| funkos.each do |funko|
local = @options.@bool["local"] local = @options.@bool["local"]
@ -188,7 +188,7 @@ module Faaso
end end
def run def run
funkos = Funko::Funko.from_paths(@arguments) funkos = Funko.from_paths(@arguments)
funkos.each do |funko| funkos.each do |funko|
# Create temporary build location # Create temporary build location
dst_path = Path.new("export", funko.name) dst_path = Path.new("export", funko.name)

View File

@ -3,10 +3,7 @@ require "file_utils"
require "yaml" require "yaml"
# A funko, built from its source metadata # A funko, built from its source metadata
module Funko class Funko
extend self
class Funko
include YAML::Serializable include YAML::Serializable
# Required, the name of the funko. Must be unique across FaaSO # Required, the name of the funko. Must be unique across FaaSO
@ -71,19 +68,15 @@ module Funko
# Get all the funkos docker knows about. # Get all the funkos docker knows about.
def self.from_docker : Array(Funko) def self.from_docker : Array(Funko)
docker_api = Docr::API.new(Docr::Client.new) docker_api = Docr::API.new(Docr::Client.new)
names = [] of String names = Set(String).new
funko_containers = docker_api.containers.list( docker_api.images.list(all: true).select { |i|
all: true, next if i.@repo_tags.nil?
).each { |container| i.@repo_tags.as(Array(String)).each { |tag|
p! container.@names names << tag.split(":", 2)[0].split("-", 2)[1] if tag.starts_with?("faaso-")
container.@names.each { |name|
names << name.split("-", 2)[1].lstrip("/") if name.starts_with?("/faaso-")
} }
} }
pp! names pp! names
from_names(names.to_a)
from_names(names.to_a.sort!)
end end
# Setup the target directory `path` with all the files needed # Setup the target directory `path` with all the files needed
@ -144,14 +137,6 @@ module Funko
) )
end end
# Descriptive status for the funko
def status
status = self.containers.map { |container|
container.@status
}.join(", ")
status.empty? ? "Stopped" : status
end
# Is any instance of this funko running? # Is any instance of this funko running?
def running? def running?
self.containers.any? { |container| self.containers.any? { |container|
@ -224,5 +209,4 @@ module Funko
docker_api.containers.start(response.@id) if autostart docker_api.containers.start(response.@id) if autostart
response.@id response.@id
end end
end
end end

View File

@ -1,42 +0,0 @@
module Secrets
extend self
SECRETS = Hash(String, String).new
SECRET_PATH = "./secrets/"
# TODO: sanitize all inputs
# Store secrets in a tree of files
def update_secrets
# Save new secrets
SECRETS.map do |_name, value|
funko, name = _name.split("-", 2)
funko_dir = Path.new(SECRET_PATH, funko)
Dir.mkdir_p(funko_dir)
File.write(Path.new(funko_dir, name), value)
end
# Delete secrets not in the hash
Dir.glob(Path.new(SECRET_PATH, "*")).each do |funko_dir|
funko = File.basename(funko_dir)
Dir.glob(Path.new(funko_dir, "*")).each do |secret_file|
name = File.basename(secret_file)
unless SECRETS.has_key?("#{funko}-#{name}")
File.delete(secret_file)
end
end
end
end
# Load secrets from the disk
def load_secrets
Dir.glob(Path.new(SECRET_PATH, "*")).each do |funko_dir|
funko = File.basename(funko_dir)
Dir.glob(Path.new(funko_dir, "*")).each do |secret_file|
name = File.basename(secret_file)
value = File.read(secret_file)
SECRETS["#{funko}-#{name}"] = value
end
end
end
end
Secrets.load_secrets

View File

@ -1,26 +1,7 @@
<%- result.each do |f| -%> <%- funkos.each do |funko| -%>
<tr> <tr>
<td><%= f["name"] %></td> <td><%= funko.name %></td>
<td><%= f["status"] %></td> <td>sarasa</td>
<td> <td><button>DOSTUFF</button></td>
<%- if f["state"] == "running" -%>
<button state="disabled">Start</button>
<button>Pause</button>
<button>Stop</button>
<button>Restart</button>
<%- end -%>
<%- if f["state"] == "paused" -%>
<button>Start</button>
<button disabled>Pause</button>
<button>Stop</button>
<button>Restart</button>
<%- end -%>
<%- if f["state"] == "stopped" -%>
<button>Start</button>
<button disabled>Pause</button>
<button disabled>Stop</button>
<button disabled>Restart</button>
<%- end -%>
</td>
</tr> </tr>
<%- end -%> <%- end -%>