require 'toolrack' require_relative "user_prompt" module Hitcher module CliOps module RunOps include Hitcher::UserPrompt include Antrapol::ToolRack::ConditionUtils class RunCommandException < StandardError; end #### HERE IS THE FINAL METHOD SIGNATURE def run(inst, opts = { }) raise Exception, "Parameter must be a Hash object" if not opts.is_a?(Hash) opts[:interactive] = inst.interactive_mode || true opts[:tty] = inst.tty_mode || true run_container(inst, opts) end # run def run_prompt(inst, opts = { }) raise Exception, "Parameter must be a Hash object" if not opts.is_a?(Hash) op = { } op.merge!(opts) command = opts[:command] || "/bin/bash --login" if command == "/bin/bash --login" op[:interactive] = true op[:tty] = true else op[:interactive] = inst.interactive_mode op[:tty] = inst.tty_mode end run_container(inst, op) end # run_prompt def run_new_prompt(inst, opts = { }) raise Exception, "Parameter must be a Hash object" if not opts.is_a?(Hash) #nname = "#{inst.cName}_#{Time.zone.local.strftime("%Y%m%d_%H%M%S_%L%N")}" opt = { } opt.merge!(opts) opt[:new_instance] = true command = opts[:command] || "/bin/bash --login" if command == "/bin/bash --login" opt[:interactive] = true opt[:tty] = true else opt[:interactive] = inst.interactive_mode opt[:tty] = inst.tty_mode end run_container(inst, opt) end # run_new_prompt ####### def run_container(inst, opts = { }) loop do res, st, id = inst.command_executor.container_exist?(opts) if res case st when :stopped STDOUT.puts "Container '#{inst.cName}' has stopped! Reviving the container..." if not_empty?(opts[:command]) rmech, rval = inst.command_executor.run_command_in_container(opts[:command], opts) break else # assuming the container is launching up something via the CMD or ENTRYPOINT or else the # container will die back after startup... rcst, rcout, rcerr = inst.command_executor.start_container(opts) if not rcst raise RunCommandException, "Failed to run container '#{name}'. Error was : #{rcerr.join("\n")}" end end when :running STDOUT.puts "Container '#{inst.cName}' is running!" # break the loop rmech, rval = inst.command_executor.run_command_in_container(opts[:command], opts) case rmech when :file, :term break else raise RunCommandException, "Run command in container failed with mechanism '#{rmech}'" end else raise RunCommandException, "Container found but neither in running or stopped status" end else # container not exist! iest, ieout, ieerr = inst.command_executor.image_exist?(opts) if not_empty?(ieout) STDOUT.puts "Image '#{inst.image}' exist! Creating container..." mech, v = inst.command_executor.create_container(opts) case mech when :file break when :term break else raise RunCommandException, "Create container command failed with mechanism '#{mech}'" end else STDOUT.puts "Image '#{inst.image}' does not exist! Proceed to build image..." bist, biout, bierr = inst.command_executor.build_image(opts) if is_empty?(bierr) STDOUT.puts "Image '#{inst.image}' built!" # should loop back to run the container else raise RunCommandException, "Build image command failed. Error was : #{bierr.join("\n")}" end end end end end # run_container end end end