Cleanup tags/names/etc, refactors, use image history

This commit is contained in:
Roberto Alsina 2024-06-29 14:36:11 -03:00
parent 3aa58435f8
commit 3333c4f67f
6 changed files with 84 additions and 26 deletions

View File

@ -72,4 +72,4 @@ Probably some `metadata.yml` that is *not* in the template.
# Implementation Ideas
* caddy for proxy? It's simple, fast, API-configurable.
* Local docker registry for images? See https://www.docker.com/blog/how-to-use-your-own-registry-2/
* Local docker registry for images? See https://www.docker.com/blog/how-to-use-your-own-registry-2/ (maybe later)

View File

@ -1,3 +1,3 @@
get "/" do
"Hello World from Crystal!"
"Hello World Crystal!"
end

View File

@ -12,3 +12,7 @@ shards:
git: https://github.com/ralsina/docr.git
version: 0.1.1+git.commit.18f15cc7111b1d0c63347c7cca07aee9ec87a7a8
kiwi:
git: https://github.com/ralsina/kiwi.git
version: 0.1.0+git.commit.65059b87771238593a28b2b8b9fdf77d8e2b9e89

View File

@ -19,3 +19,6 @@ dependencies:
branch: add_exposed_ports
commander:
github: mrrooijen/commander
kiwi:
github: ralsina/kiwi
branch: master

View File

@ -1,9 +1,10 @@
require "./funko.cr"
require "commander"
require "docr"
require "docr/utils.cr"
require "file_utils"
require "kiwi/file_store"
require "uuid"
require "./funko.cr"
# FIXME make it configurable
REPO = "localhost:5000"
@ -12,6 +13,9 @@ REPO = "localhost:5000"
module Faaso
VERSION = "0.1.0"
# A simple persistent k/v store
store = Kiwi::FileStore.new(".kiwi")
module Commands
class Build
@arguments : Array(String) = [] of String
@ -56,17 +60,11 @@ module Faaso
# FIXME: this should be configurable
repo = REPO
tag = "#{repo}/#{funko.name}:latest"
docker_api = Docr::API.new(Docr::Client.new)
docker_api.images.build(
context: tmp_dir.to_s,
tags: [tag, "#{funko.name}:latest"]) { }
puts "Pushing to repo as #{tag}"
docker_api.images.tag(repo: repo, name: slug, tag: "latest")
# FIXME: pushing is broken because my test registry has no auth
# docker_api.images.push(name: slug, tag: "latest", auth: "")
tags: ["#{funko.name}:latest"]) { }
end
end
end
@ -84,23 +82,51 @@ module Faaso
funkos = Funko.from_paths(@arguments)
funkos.each do |funko|
repo = REPO
tag = "#{repo}/#{funko.name}:latest"
container_name = "faaso-#{funko.name}"
docker_api = Docr::API.new(Docr::Client.new)
# Pull image from registry
docker_api.images.create(image: tag)
# docker_api.images.create(image: tag)
containers = docker_api.containers.list(all: true)
# If it's running, do nothing
# FIXME: When reusing a paused/exited container, check that
# the version of the image is the correct one, otherwise purge them.
# Get image history, sorted newer image first
begin
images = docker_api.images.history(
name: funko.name
).sort { |a, b| b.@created <=> a.@created }.map(&.@id)
rescue ex : Docr::Errors::DockerAPIError
puts "Error: no images available for #{funko.name}:latest"
puts ex
next
end
latest_image = images[0]
# Filter by name so only faaso-thisfunko are affected from now on
# sorted newer image first
containers = docker_api.containers.list(
all: true,
filters: {"name" => [container_name]}
).sort { |a, b| (images.index(b.@image_id) || 9999) <=> (images.index(a.@image_id) || 9999) }
pp! images
pp! containers.map { |c| images.index(c.@image_id) }
# If it's already up, do nothing
if containers.any? { |container|
container.@image == tag && container.@state == "running"
is_running = container.@state == "running"
is_old = container.@image_id != latest_image
p! container.@image_id
puts "Warning: running outdated version" if is_running && is_old
is_running
}
puts "#{funko.name} is already running"
puts "#{funko.name} is already up"
next
end
# If it is paused, unpause it
paused = containers.select { |container|
container.@image == tag && container.@state == "paused"
container.@state == "paused"
}
if paused.size > 0
puts "Resuming existing paused container"
@ -110,7 +136,7 @@ module Faaso
# If it is exited, start it
existing = containers.select { |container|
container.@image == tag && container.@state == "exited"
container.@state == "exited"
}
puts "Starting function #{funko.name}"
@ -123,7 +149,7 @@ module Faaso
# Creating from scratch
puts "Creating new container"
conf = Docr::Types::CreateContainerConfig.new(
image: tag,
image: "#{funko.name}:latest",
hostname: funko.name,
# Port in the container side
exposed_ports: {"#{funko.port}/tcp" => {} of String => String},
@ -135,10 +161,9 @@ module Faaso
)
)
# FIXME: name should be unique
response = docker_api.containers.create(name: "fungus", config: conf)
response = docker_api.containers.create(name: container_name, config: conf)
response.@warnings.each { |msg| puts "Warning: #{msg}" }
container_id = response.@id
# container_id = response.@id
docker_api.containers.start(response.@id)
# TODO: wait until container is running before next
end
@ -167,5 +192,22 @@ module Faaso
end
end
end
class Deploy
@arguments : Array(String) = [] of String
@options : Commander::Options
def initialize(options, arguments)
@options = options
@arguments = arguments
end
def run
@arguments.each do |arg|
puts "Stopping function... #{arg}"
# TODO: Everything
end
end
end
end
end

View File

@ -7,8 +7,8 @@ cli = Commander::Command.new do |cmd|
cmd.commands.add do |command|
command.use = "build"
command.short = "Build a function"
command.long = "Build a function's Docker image and optionally upload it to registry"
command.short = "Build a funko"
command.long = "Build a funko's Docker image and upload it to registry"
command.run do |options, arguments|
Faaso::Commands::Build.new(options, arguments).run
end
@ -16,13 +16,22 @@ cli = Commander::Command.new do |cmd|
cmd.commands.add do |command|
command.use = "up"
command.short = "Start a function"
command.long = "Start a function in a container"
command.short = "Ensure funkos are running"
command.long = "Start/unpause/create containers for requested funkos and ensure they are up."
command.run do |options, arguments|
Faaso::Commands::Up.new(options, arguments).run
end
end
cmd.commands.add do |command|
command.use = "deploy"
command.short = "Deploy latest images"
command.long = "Update containers for all funkos to latest image."
command.run do |options, arguments|
Faaso::Commands::Deploy.new(options, arguments).run
end
end
cmd.commands.add do |command|
command.use = "down"
command.short = "Stop a function"