require_relative 'cli/user_info' module Dockerun # Generate Dockerfile class Dfile include TR::CondUtils def initialize(config) @_config = config end # DSL def set_image_name(val) @image_name = val end def image_name @image_name end def is_image_name_given? not_empty?(@image_name) end def generated_image_name if @_genImgName.nil? @_genImgName = "#{File.basename(Dir.getwd.gsub(" ","-"))}_docker_image" end @_genImgName end # DSL def output=(val) @output = val end def output_filename @output end def install(*app) @installApp = app end def required_app @installApp.nil? ? [] : @installApp end def set_command(*val) @cmd = val end def command @cmd end def default_command ["/bin/bash"] end def is_command_given? not_empty?(command) end def base_image=(img) @base_image = img end def base_image @base_image end def set_workdir(bool = true) @set_workdir = bool end def is_set_workdir? @set_workdir.nil? ? true : @set_workdir end def skip_update(bool = false) @skip_update = bool end def skip_update? @skip_update.nil? ? false : @skip_update end def skip_upgrade(bool = false) @skip_upgrade = bool end def skip_upgrade? @skip_upgrade.nil? ? false : @skip_upgrade end def keep_dockerfile(bool = true) @keep_dockerfile = bool end def keep_dockerfile? @keep_dockerfile.nil? ? true : @keep_dockerfile end # for context to install listener def listener(&block) @listener = block end def generate(opts = {}) opts = {} if opts.nil? config = @_config raise Error, "Config is required" if config.nil? cont = [] cont << "FROM #{base_image}" cont << "" pkgMgr = pkg_mgr(config) if not skip_update? or not skip_upgrade? st = [] st << "#{pkgMgr} update" if not skip_update? st << "#{pkgMgr} -y upgrade" if not skip_upgrade? cont << "RUN #{st.join(" && ")}" if not_empty?(st) cont << "" end cb = trigger_listener(:dockerfile_before_install_app) cont << cb if not_empty?(cb) cont << "RUN #{pkgMgr} -y install #{required_app.join(" ")}" cont << "" cb = trigger_listener(:dockerfile_after_install_app) cont << cb if not_empty?(cb) if config.set_current_user? #RUN groupadd -f -g <%= @user_group_id %> <%= @user_group_name %> && useradd -u <%= @user_id %> -g <%= @user_group_id %> -m <%= @user_login %> && usermod -aG sudo <%= @user_login %> && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers #USER <%= @user_login %> uInfo = Dockerun::Cli::UserInfo.user_info gInfo = Dockerun::Cli::UserInfo.group_info uCmd = [] uCmd << "groupadd -f -g" uCmd << gInfo[:gid] uCmd << gInfo[:group_name] uCmd << "&& useradd" uCmd << "-u" uCmd << uInfo[:uid] uCmd << "-g" uCmd << gInfo[:gid] uCmd << "-m" uCmd << uInfo[:login] uCmd << "&& usermod -aG sudo" uCmd << uInfo[:login] uCmd << "&& echo '#{uInfo[:login]} ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers" cb = trigger_listener(:dockerfile_before_add_user) cont << cb if not_empty?(cb) cont << "RUN #{pkgMgr} -y install sudo && #{uCmd.join(" ")}" cont << "USER #{uInfo[:login]}" cont << "" cb = trigger_listener(:dockerfile_after_add_user) cont << cb if not_empty?(cb) end cb = trigger_listener(:dockerfile_before_workdir) cont << cb if not_empty?(cb) if config.is_workdir_given? and is_set_workdir? cont << "WORKDIR #{config.workdir}" cont << "" end cb = trigger_listener(:dockerfile_after_workdir) cont << cb if not_empty?(cb) cb = trigger_listener(:dockerfile_before_command) cont << cb if not_empty?(cb) cont << "CMD [\"#{command.join(",")}\"]" if is_command_given? cont.join("\n") end private def pkg_mgr(config) case config.platform when :debian "apt-get" when :fedora "dnf" else raise Error, "Unknown package manager for platform '#{config.platform}'" end end def trigger_listener(evt, *argv) if not @listener.nil? argv << { dfile: self } @listener.call(evt, *argv) end end end end