General rewrite to support scales different than 1
This commit is contained in:
68
src/commands/build.cr
Normal file
68
src/commands/build.cr
Normal file
@@ -0,0 +1,68 @@
|
||||
module Faaso
|
||||
module Commands
|
||||
# Build images for one or more funkos from source
|
||||
struct Build
|
||||
def run(options, folders : Array(String))
|
||||
funkos = Funko::Funko.from_paths(folders)
|
||||
|
||||
if options["--local"]
|
||||
funkos.each do |funko|
|
||||
# Create temporary build location
|
||||
tmp_dir = Path.new("tmp", UUID.random.to_s)
|
||||
Dir.mkdir_p(tmp_dir) unless File.exists? tmp_dir
|
||||
funko.prepare_build tmp_dir
|
||||
|
||||
Log.info { "Building function... #{funko.name} in #{tmp_dir}" }
|
||||
funko.build tmp_dir
|
||||
end
|
||||
else # Running against a server
|
||||
funkos.each do |funko|
|
||||
# Create a tarball for the funko
|
||||
buf = IO::Memory.new
|
||||
Compress::Gzip::Writer.open(buf) do |gzip|
|
||||
Crystar::Writer.open(gzip) do |tw|
|
||||
Dir.glob("#{funko.path}/**/*").each do |path|
|
||||
next unless File.file? path
|
||||
rel_path = Path[path].relative_to funko.path
|
||||
file_info = File.info(path)
|
||||
hdr = Crystar::Header.new(
|
||||
name: rel_path.to_s,
|
||||
mode: file_info.permissions.to_u32,
|
||||
size: file_info.size,
|
||||
)
|
||||
tw.write_header(hdr)
|
||||
tw.write(File.read(path).to_slice)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tmp = File.tempname
|
||||
File.open(tmp, "w") do |outf|
|
||||
outf << buf
|
||||
end
|
||||
|
||||
url = "#{FAASO_SERVER}funkos/build/"
|
||||
|
||||
begin
|
||||
Log.info { "Uploading funko to #{FAASO_SERVER}" }
|
||||
response = Crest.post(
|
||||
url,
|
||||
{"funko.tgz" => File.open(tmp), "name" => "funko.tgz"},
|
||||
user: "admin", password: "admin"
|
||||
)
|
||||
Log.info { "Build finished successfully." }
|
||||
body = JSON.parse(response.body)
|
||||
Log.info { body["stdout"] }
|
||||
rescue ex : Crest::InternalServerError
|
||||
Log.error { "Error building funko #{funko.name} from #{funko.path}" }
|
||||
body = JSON.parse(ex.response.body)
|
||||
Log.info { body["stdout"] }
|
||||
Log.error { body["stderr"] }
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
18
src/commands/export.cr
Normal file
18
src/commands/export.cr
Normal file
@@ -0,0 +1,18 @@
|
||||
module Faaso
|
||||
module Commands
|
||||
struct Export
|
||||
def run(options, source : String, destination : String)
|
||||
funko = Funko::Funko.from_paths([source])[0]
|
||||
# Create temporary build location
|
||||
dst_path = destination
|
||||
if File.exists? dst_path
|
||||
Log.error { "#{dst_path} already exists, not exporting #{funko.path}" }
|
||||
return 1
|
||||
end
|
||||
Log.info { "Exporting #{funko.path} to #{dst_path}" }
|
||||
Dir.mkdir_p(dst_path)
|
||||
funko.prepare_build Path[dst_path]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
85
src/commands/scale.cr
Normal file
85
src/commands/scale.cr
Normal file
@@ -0,0 +1,85 @@
|
||||
module Faaso
|
||||
module Commands
|
||||
# Bring up one or more funkos by name.
|
||||
#
|
||||
# This doesn't guarantee that they will be running the latest
|
||||
# version, and it will try to recicle paused and exited containers.
|
||||
#
|
||||
# If there is no other way, it will create a brand new container with
|
||||
# the latest known image and start it.
|
||||
#
|
||||
# If there are no images for the funko, it will fail to bring it up.
|
||||
struct Scale
|
||||
def local(options, name, scale)
|
||||
funko = Funko::Funko.from_names([name])[0]
|
||||
# Asked about scale
|
||||
if !scale
|
||||
Log.info { "Funko #{name} has a scale of #{funko.scale}" }
|
||||
return 0
|
||||
end
|
||||
# Asked to set scale
|
||||
if funko.image_history.empty?
|
||||
Log.error { "Error: no images available for #{funko.name}:latest" }
|
||||
exit 1
|
||||
end
|
||||
funko.scale(scale.as(String).to_i)
|
||||
end
|
||||
|
||||
def remote(options, name, scale)
|
||||
if !scale
|
||||
response = Crest.get(
|
||||
"#{FAASO_SERVER}funkos/#{name}/scale/", \
|
||||
user: "admin", password: "admin")
|
||||
else
|
||||
response = Crest.post(
|
||||
"#{FAASO_SERVER}funkos/#{name}/scale/",
|
||||
{"scale" => scale}, user: "admin", password: "admin")
|
||||
end
|
||||
body = JSON.parse(response.body)
|
||||
Log.info { body["output"] }
|
||||
rescue ex : Crest::InternalServerError
|
||||
Log.error { "Error scaling funko #{name}" }
|
||||
body = JSON.parse(ex.response.body)
|
||||
Log.info { body["output"] }
|
||||
exit 1
|
||||
end
|
||||
|
||||
def run(options, name, scale)
|
||||
if options["--local"]
|
||||
return local(options, name, scale)
|
||||
end
|
||||
remote(options, name, scale)
|
||||
|
||||
# case self
|
||||
# when .running?
|
||||
# # If it's already up, do nothing
|
||||
# # FIXME: bring back out-of-date warning
|
||||
# Log.info { "#{funko.name} is already up" }
|
||||
# when .paused?
|
||||
# # If it is paused, unpause it
|
||||
# Log.info { "Resuming existing paused container" }
|
||||
# funko.unpause
|
||||
# when .exited?
|
||||
# Log.info { "Starting function #{funko.name}" }
|
||||
# Log.info { "Restarting existing exited container" }
|
||||
# funko.start
|
||||
# else
|
||||
# # Only have an image, deploy from scratch
|
||||
# Faaso.setup_network # We need it
|
||||
# Log.info { "Creating and starting new container" }
|
||||
# funko.create_container(autostart: true)
|
||||
|
||||
# (1..5).each { |_|
|
||||
# break if funko.running?
|
||||
# sleep 0.1.seconds
|
||||
# }
|
||||
# if !funko.running?
|
||||
# Log.warn { "Container for #{funko.name} is not running yet" }
|
||||
# next
|
||||
# end
|
||||
# Log.info { "Container for #{funko.name} is running" }
|
||||
# end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
31
src/commands/status.cr
Normal file
31
src/commands/status.cr
Normal file
@@ -0,0 +1,31 @@
|
||||
module Faaso
|
||||
module Commands
|
||||
struct Status
|
||||
def local(options, name)
|
||||
funko = Funko::Funko.from_names([name])[0]
|
||||
Log.info { "Name: #{funko.name}" }
|
||||
Log.info { "Scale: #{funko.scale}" }
|
||||
containers = funko.containers
|
||||
Log.info { "Containers: #{funko.containers.size}" }
|
||||
containers.each do |container|
|
||||
Log.info { " #{container.@names[0]} #{container.status}" }
|
||||
end
|
||||
images = funko.images
|
||||
Log.info { "Images: #{images.size}" }
|
||||
images.each do |image|
|
||||
Log.info { " #{image.repo_tags} #{image.created}" }
|
||||
end
|
||||
end
|
||||
|
||||
def remote(options, name)
|
||||
end
|
||||
|
||||
def run(options, name)
|
||||
if options["--local"]
|
||||
return local(options, name)
|
||||
end
|
||||
remote(options, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user