lib/dockdev.rb in dockdev-0.3.8 vs lib/dockdev.rb in dockdev-0.4.0
- old
+ new
@@ -3,86 +3,199 @@
require 'teLogger'
require 'toolrack'
require 'docker/cli'
require 'colorize'
+require 'tty/prompt'
+
require_relative "dockdev/version"
require_relative 'dockdev/workspace'
require_relative 'dockdev/image'
require_relative 'dockdev/container'
+require_relative 'dockdev/dockdev_config'
+
module Dockdev
include TR::CondUtils
class Error < StandardError; end
# Your code goes here...
+ # main entry points to start docker
def self.with_running_container(contName, opts = {})
+ pmt = TTY::Prompt.new
root = opts[:root]
cmd = opts[:command]
- ctx = Dockdev::Context::ContextManager.instance.get_context(root)
- logger.debug("Found context : #{ctx}")
+ ddConf = load_config(root)
cont = Container.new(contName)
if cont.has_container?
+
+ logger.debug "Container '#{contName}' already exist. Just run the container"
if cont.running?
cont.attach_and_exec(command: cmd)
else
cont.start_with_command(command: cmd)
end
+
else
+
+ logger.debug "Container '#{contName}' does not exist. Creating the container"
+
img = Image.new(contName)
ws = opts[:workspace] || root
wss = Workspace.new(ws)
- if img.has_image?
- mount = { root => File.join("/opt",File.basename(root)) }
- port = {}
- ctx.each do |cctx|
- mnts = cctx.process_mount(dir_inside_docker: "/opt")
- logger.debug "Mount points by context : #{mnts}"
- mount.merge!(mnts) if not mnts.empty?
+ # root directory is mounted by default
+ ddConf.add_mount(root, File.join(ddConf.workdir,File.basename(root)))
- prt = cctx.process_port
- port.merge!(prt) if not prt.empty?
+ ctx = Dockdev::Context::ContextManager.instance.get_context(root)
+ logger.debug("Found context : #{ctx}")
- logger.debug "Ports by context #{cctx} : #{prt}"
+ ctx.each do |name, cctx|
+
+ if ddConf.is_context_should_skip?(name)
+ logger.debug "Context '#{name}' is asked to be skipped"
+ next
end
- param = { command: cmd, mounts: mount }
- param[:ports] = port if not port.empty?
+ logger.debug "Appying context '#{name}' "
+ # here allow context to add additional Dockerfile entries, mounts and ports
+ ddConf = cctx.apply_context(ddConf)
+ end
- img.new_container(cont.name, param)
+ ddConf.manual_activated_context.each do |cctx|
+ mctx = Dockdev::Context::ContextManager.instance.registered_context_by_name(cctx)
+ logger.debug "Executing manual activated context : #{mctx}"
+ ddConf = mctx.apply_context(ddConf) if not mctx.nil?
+ end
- elsif wss.has_dockerfile?
- img.build(wss.dockerfile)
-
- mount = { root => File.join("/opt",File.basename(root)) }
- port = {}
- ctx.each do |cctx|
- mnt = cctx.process_mount(dir_inside_docker: "/opt")
- mount.merge!(mnt) if not mnt.empty?
+ if not img.has_image?
- logger.debug "Mount points by context #{cctx} : #{mnt}"
+ if wss.has_dockerfile?
- prt = cctx.process_port
- port.merge!(prt) if not prt.empty?
+ if wss.has_multiple_dockerfiles?
- logger.debug "Ports by context #{cctx} : #{prt}"
- end
+ selDockerFile = pmt.select("Please select one of the Dockerfile to proceed : ") do |m|
+ wss.dockerfiles.each do |df|
+ m.choice File.basename(df), df
+ end
+ end
- param = { command: cmd, mounts: mount }
- param[:ports] = port if not port.empty?
+ else
+ selDockerFile = wss.dockerfile
+ end
- img.new_container(cont.name, param)
+ # Delegated to config file to allow
+ # config file to embed addtional entries (if there is any) and proceed to build it.
+ # During the process it is very likey a temporary Dockerfile shall be created since
+ # docker cli works on file basis and this temporary file need to be managed after the process.
+ # Hence this makes more sense to let the config handle all those inside the operation
+ res = ddConf.build_image(img, selDockerFile, root: root)
+ raise Error, "Image failed to be built. Error was : #{res.err_stream}" if res.failed?
+ STDOUT.puts "\n Image '#{contName}' built successfully\n\n".green
+ #img.build(wss.dockerfile)
- else
- raise Error, "\n No image and no Dockerfile found to build the image found. Operation aborted. \n\n".red
+ else
+ raise Error, "\n No image and no Dockerfile found to build the image. Operation aborted. \n\n".red
+
+ end
end
+
+ # image already exist!
+ # Since reach here means container doesn't exist yet.
+ # Proceed to create container
+
+ param = { command: cmd, mounts: ddConf.mounts, ports: ddConf.ports }
+ img.new_container(cont.name, param)
+
+ #if img.has_image?
+ #
+ # # has image but no container
+ # ctx.each do |cctx|
+ #
+ # ddConf = cctx.apply_context(ddConf)
+
+ # #cctx.process_mount(dir_inside_docker: ddConf.workdir).each do |host,docker|
+ # # logger.debug "Mount points by context '#{cctx}' : #{host} => #{docker}"
+ # # ddConf.add_mount(host, docker)
+ # #end
+
+ # #cctx.process_port.each do |host, docker|
+ # # logger.debug "Ports mapping by context '#{cctx}' : #{host} => #{docker}"
+ # # ddConf.add_port(host, docker)
+ # #end
+
+ # #mnts = cctx.process_mount(dir_inside_docker: ddConf.workdir)
+ # #logger.debug "Mount points by context : #{mnts}"
+
+ # #mount.merge!(mnts) if not mnts.empty?
+
+ # #prt = cctx.process_port
+ # #port.merge!(prt) if not prt.empty?
+
+ # #logger.debug "Ports by context #{cctx} : #{prt}"
+ # end
+
+ # #param = { command: cmd, mounts: mount }
+ # #param[:ports] = port if not port.empty?
+ # param = { command: cmd, mounts: ddConf.mounts, ports: ddConf.ports }
+
+ # img.new_container(cont.name, param)
+
+ #elsif wss.has_dockerfile?
+
+ # logger.debug "Dockerfile '#{wss.dockerfile}' found. Proceed building the image."
+
+ # # Delegated to config file to allow
+ # # config file to embed addtional entries (if there is any) and proceed to build it.
+ # # During the process it is very likey a temporary Dockerfile shall be created since
+ # # docker cli works on file basis and this temporary file need to be managed after the process.
+ # # Hence this makes more sense to let the config handle all those inside the operation
+ # ddConf.build_image(img, wss, root: root)
+ # #img.build(wss.dockerfile)
+ #
+ # ddConf.add_mount(root, File.join(ddConf.workdir,File.basename(root)))
+ # #mount = { root => File.join(ddConf.workdir,File.basename(root)) }
+ # #port = {}
+ # ctx.each do |cctx|
+
+ # ddConf = cctx.apply_context(ddConf)
+
+ # #cctx.process_mount(dir_inside_docker: ddConf.workdir).each do |host,docker|
+ # # logger.debug "Mount points by context '#{cctx}' : #{host} => #{docker}"
+ # # ddConf.add_mount(host, docker)
+ # #end
+
+ # #cctx.process_port.each do |host, docker|
+ # # logger.debug "Ports mapping by context '#{cctx}' : #{host} => #{docker}"
+ # # ddConf.add_port(host, docker)
+ # #end
+
+ # #mnt = cctx.process_mount(dir_inside_docker: ddConf.workdir)
+ # #mount.merge!(mnt) if not mnt.empty?
+
+ # #logger.debug "Mount points by context #{cctx} : #{mnt}"
+
+ # #prt = cctx.process_port
+ # #port.merge!(prt) if not prt.empty?
+
+ # #logger.debug "Ports by context #{cctx} : #{prt}"
+ # end
+
+ # #param = { command: cmd, mounts: mount }
+ # #param[:ports] = port if not port.empty?
+ # param = { command: cmd, mounts: ddConf.mounts, ports: ddConf.ports }
+
+ # img.new_container(cont.name, param)
+
+ #else
+ # raise Error, "\n No image and no Dockerfile found to build the image found. Operation aborted. \n\n".red
+ #end
end
end
def self.destroy(contName, opts = {})
@@ -95,9 +208,36 @@
img = Image.new(contName)
if img.has_image?
img.destroy
end
+ end
+
+ # detect if the additional configuration file exist
+ def self.load_config(root)
+
+ ddConf = DockdevConfig.new
+ DockdevConfig.load(root) do |ops, *args|
+ case ops
+ when :found_more
+ found = args.first
+ pmt = TTY::Prompt.new
+ selConf = pmt.select("There are more config files found. Please select one of the files below :") do |m|
+ found.each do |f|
+ m.choice Pathname.new(f).relative_path_from(root),f
+ end
+ end
+ ddConf = DockdevConfig.new(selConf)
+ when :found
+ ddConf = DockdevConfig.new(args.first)
+ else
+ logger.debug "Load config got ops : #{ops}"
+ end
+ end
+
+ logger.debug "Loaded config : #{ddConf}"
+ ddConf
+
end
def self.logger(tag = nil, &block)
if @_logger.nil?
@_logger = TeLogger::Tlogger.new(STDOUT)