diff --git a/public/index.html b/public/index.html index ca2004a..40cf5a9 100644 --- a/public/index.html +++ b/public/index.html @@ -4,22 +4,30 @@ - + +

Your Funko Collection

-
-
- - - - - - - - + +
+ +
NameStatusAction
+ + + + + + + - - - - +
NameStatusAction
+ +
+ + diff --git a/src/daemon/funko.cr b/src/daemon/funko.cr index 02ae4a8..cc028d2 100644 --- a/src/daemon/funko.cr +++ b/src/daemon/funko.cr @@ -5,6 +5,34 @@ require "../funko.cr" module Funko extend self + get "/funkos/:name/pause/" do |env| + funko = Funko.from_names([env.params.url["name"]])[0] + funko.pause + funko.wait_for("paused", 5) + end + + get "/funkos/:name/unpause/" do |env| + funko = Funko.from_names([env.params.url["name"]])[0] + funko.unpause + funko.wait_for("running", 5) + end + + get "/funkos/:name/start/" do |env| + funko = Funko.from_names([env.params.url["name"]])[0] + funko.start + funko.wait_for("running", 5) + end + + get "/funkos/:name/stop/" do |env| + funko = Funko.from_names([env.params.url["name"]])[0] + begin + funko.stop + funko.wait_for("exited", 5) + rescue ex : Docr::Errors::DockerAPIError + halt env, status_code: 500, response: "Failed to stop container" + end + end + get "/funkos/" do |env| funkos = Funko.from_docker funkos.sort! { |a, b| a.name <=> b.name } diff --git a/src/funko.cr b/src/funko.cr index 75ef3ca..c7f03de 100644 --- a/src/funko.cr +++ b/src/funko.cr @@ -173,6 +173,18 @@ module Funko } end + # Pause running container + def pause + docker_api = Docr::API.new(Docr::Client.new) + images = self.image_history + running = self.containers.select { |container| + container.@state == "running" + }.sort! { |i, j| + (images.index(j.@image_id) || 9999) <=> (images.index(i.@image_id) || 9999) + } + docker_api.containers.pause(running[0].@id) unless running.empty? + end + # Unpause paused container with the newer image def unpause docker_api = Docr::API.new(Docr::Client.new) @@ -192,17 +204,54 @@ module Funko } end - # Restart exited container with the newer image + # Start exited container with the newer image + # or unpause paused container def start - # FIXME refactor DRY with unpause + if self.exited? + docker_api = Docr::API.new(Docr::Client.new) + images = self.image_history + exited = self.containers.select { |container| + container.@state == "exited" + }.sort! { |i, j| + (images.index(j.@image_id) || 9999) <=> (images.index(i.@image_id) || 9999) + } + docker_api.containers.restart(exited[0].@id) unless exited.empty? + elsif self.paused? + self.unpause + end + end + + # Stop container with the newer image + def stop docker_api = Docr::API.new(Docr::Client.new) images = self.image_history - exited = self.containers.select { |container| - container.@state == "exited" - }.sort! { |i, j| + containers = self.containers.sort! { |i, j| (images.index(j.@image_id) || 9999) <=> (images.index(i.@image_id) || 9999) } - docker_api.containers.restart(exited[0].@id) unless exited.empty? + return docker_api.containers.stop(containers[0].@id) unless containers.empty? + nil + end + + # Wait up to `t` seconds for the funko to reach the requested `state` + def wait_for(state : String, t) + channel = Channel(Nil).new + spawn do + sleep 0.1.seconds + case state + when "exited" + if self.exited? + channel.send(nil) + end + when "running" + if self.running? + channel.send(nil) + end + when "paused" + if self.paused? + channel.send(nil) + end + end + end end # Create a container for this funko diff --git a/src/views/funkos.ecr b/src/views/funkos.ecr index dcf51e2..18de715 100644 --- a/src/views/funkos.ecr +++ b/src/views/funkos.ecr @@ -1,5 +1,5 @@ <%- result.each do |f| -%> - +"> <%= f["name"] %> <%- if f["name"] == "proxy" -%> Running @@ -10,24 +10,25 @@ <%- if f["name"] == "proxy" -%> <%- else -%> <%- if f["state"] == "running" -%> - - - - + + + + <%- end -%> <%- if f["state"] == "paused" -%> - - - - + + + + <%- end -%> <%- if f["state"] == "stopped" -%> - - - - + + + + <%- end -%> <%- end -%> + " src="https://htmx.org/img/bars.svg" class="htmx-indicator"> <%- end -%>