Class: NliPipeline::DockerManager
- Inherits:
-
SystemWrapper::CallWrapper
- Object
- SystemWrapper::CallWrapper
- NliPipeline::DockerManager
- Includes:
- AbstractUtil
- Defined in:
- lib/nli_pipeline/docker_manager.rb
Overview
handle docker build, save and run for nli-pipelines this DOES NOT handle docker login if you want to push to dockerhub or pull private images you’ll need to log in in advance
Instance Attribute Summary
Attributes inherited from SystemWrapper::CallWrapper
Class Method Summary collapse
- .required_args ⇒ Array[Symbol]
-
.supported_args ⇒ Hash
static methods required by NliPipeline::AbstractUtil::init_attrs.
Instance Method Summary collapse
-
#build ⇒ Boolean
build docker image.
-
#build_and_save ⇒ Boolean
save docker image as tarfile.
-
#build_args ⇒ String
Build arguments.
-
#build_commit? ⇒ Boolean
check if last commit contained build command.
-
#deploy_branch ⇒ Boolean
setup_pipeline sets fail-on-error to true for all deploys so build_commit? will raise an exception and stop the build if the last commit was not a build commit.
-
#deploy_master ⇒ Boolean
relies on tag to ensure image_name and upstream_image_name are set setup_pipeline sets fail-on-error to true for all deploys so build_commit? will raise an exception and stop the build if the last commit was not a build commit.
-
#docker_exec ⇒ Boolean
send bash command to running docker container avoid clash with exec!.
-
#initialize(**kwargs) ⇒ DockerManager
constructor
creates new DockerManager and assigns each keywoard argument as instance var with attr_reader uses image_name.tar as tar_name unless it’s explicitly set.
-
#load ⇒ Boolean
load saved docker image.
-
#prepare_run_func ⇒ Boolean
create function to bind args to on docker run.
-
#run ⇒ Boolean
if the last commit was a build commit try to load and run the image otherwise pull and run the upstream image.
-
#save ⇒ Boolean
save docker image as tarfile.
Methods included from AbstractUtil
#add_attrs, #drop_forbidden_args_message, included, #init_with_attrs, #raise_unless_all, #to_s
Methods inherited from SystemWrapper::CallWrapper
Constructor Details
#initialize(**kwargs) ⇒ DockerManager
creates new DockerManager and assigns each keywoard argument as instance var with attr_reader uses image_name.tar as tar_name unless it’s explicitly set
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/nli_pipeline/docker_manager.rb', line 35 def initialize(**kwargs) # add nlireland/ prefix to imagename if no upstream image name is set can_guess_upstream = kwargs[:image_name] && !kwargs[:upstream_image_name] kwargs[:upstream_image_name] = "nlireland/#{kwargs[:image_name]}" if can_guess_upstream # set tar name as image name if image name is set but tar name isn't can_make_tar = kwargs[:image_name] && !kwargs[:tar_name] kwargs[:tar_name] = "#{kwargs[:image_name]}.tar" if can_make_tar # set container name manually, should not be able to change it kwargs[:container_name] = 'pipeline-container' # set git branch if it's not defined # pass debug flags down to GitManager (will show warning about extra args though) kwargs[:git_branch] = GitManager.new(**kwargs).branch unless kwargs[:git_branch] init_with_attrs(**kwargs) end |
Class Method Details
.required_args ⇒ Array[Symbol]
29 30 31 |
# File 'lib/nli_pipeline/docker_manager.rb', line 29 def self.required_args [:path] end |
.supported_args ⇒ Hash
static methods required by NliPipeline::AbstractUtil::init_attrs
17 18 19 20 21 22 23 24 |
# File 'lib/nli_pipeline/docker_manager.rb', line 17 def self.supported_args { path: '', debug: false, fail_on_error: false, image_name: false, upstream_image_name: false, tar_name: false, git_branch: false, proxy: false, container_name: false, commit: true, mount: false, bash_commands: [], ports: [] } end |
Instance Method Details
#build ⇒ Boolean
build docker image
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/nli_pipeline/docker_manager.rb', line 82 def build can_build = build_commit? = 'built docker image' # if we can't build, fail early unless can_build # if --fail-on-error is passed, this will throw and exception # and "Skipping build" will not be output ret = pretty_print(custom_message: ) { false } puts('Skipping build'.yellow) return ret end command = 'docker build' # command += " --build-arg proxy=#{@proxy}" if @proxy command += build_args command += " -t #{@image_name}" if @image_name pretty_print(custom_message: ) { call_system("#{command} #{@path}") } end |
#build_and_save ⇒ Boolean
save docker image as tarfile
114 115 116 117 118 119 |
# File 'lib/nli_pipeline/docker_manager.rb', line 114 def build_and_save built = build # if the build fails quit return false unless built save end |
#build_args ⇒ String
Returns build arguments.
73 74 75 76 77 78 |
# File 'lib/nli_pipeline/docker_manager.rb', line 73 def build_args args = [] args.push("proxy=#{@proxy}") if @proxy args.push("commit=#{NliPipeline::GitManager.new.last_commit_url}") if @commit args.reduce('', &->(x, y) { x + " --build-arg #{y}" }) end |
#build_commit? ⇒ Boolean
check if last commit contained build command
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/nli_pipeline/docker_manager.rb', line 56 def build_commit? # neeed \\ since command will be passed to the shell as \[.*\] # escape chars all the way down = "[docker build] or variant not in last commit.\nFailing Build." = 'can build docker' # will match any combination of 'docker' and 'build' inside square brackets # TODO: refator to use GitManager and stub git log -1 call = NliPipeline::GitManager.new. command = "echo '#{}' | grep -o '\\[.*\\]' "\ "| grep -i 'docker' | grep -i 'build'" pretty_print(custom_message: ) do call_system(command, custom_error_message: ) end end |
#deploy_branch ⇒ Boolean
setup_pipeline sets fail-on-error to true for all deploys so build_commit? will raise an exception and stop the build if the last commit was not a build commit
211 212 213 214 215 216 217 218 219 220 |
# File 'lib/nli_pipeline/docker_manager.rb', line 211 def deploy_branch build_commit? # if gitbranch is not set, raise an error # todo: this may be unnecessary now with git branch default raise_unless_all(git_branch: @git_branch) = "pushing tag: #{@git_branch} to #{@upstream_image_name}" tag(@git_branch) push_command = "docker push #{@upstream_image_name}:#{@git_branch}" pretty_print(custom_message: ) { call_system(push_command) } end |
#deploy_master ⇒ Boolean
relies on tag to ensure image_name and upstream_image_name are set setup_pipeline sets fail-on-error to true for all deploys so build_commit? will raise an exception and stop the build if the last commit was not a build commit
193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/nli_pipeline/docker_manager.rb', line 193 def deploy_master build_commit? = ['latest', "latest-#{Time.now.strftime('%Y-%m-%d')}"] .map do |t| tag(t) = "pushing tag: #{t} to #{@upstream_image_name}" push_command = "docker push #{@upstream_image_name}:#{t}" # deploy each tag individually on the off change # that another tag for the image that wasn't created by setup_pipeline # exists and should not be pushed pretty_print(custom_message: ) { call_system(push_command) } end end |
#docker_exec ⇒ Boolean
send bash command to running docker container avoid clash with exec!
182 183 184 185 186 |
# File 'lib/nli_pipeline/docker_manager.rb', line 182 def docker_exec @bash_commands.each do |cmd| pretty_print { call_system("docker exec #{@container_name} bash -c '#{cmd}'") } end end |
#load ⇒ Boolean
load saved docker image
123 124 125 126 |
# File 'lib/nli_pipeline/docker_manager.rb', line 123 def load load_command = "docker load -i #{@path}/#{@tar_name}" pretty_print(custom_message: "loading #{@tar_name}") { call_system(load_command) } end |
#prepare_run_func ⇒ Boolean
create function to bind args to on docker run
169 170 171 172 173 174 175 176 177 |
# File 'lib/nli_pipeline/docker_manager.rb', line 169 def prepare_run_func base_command = 'docker run -id' base_command += " -v #{@path}:#{@mount}" if @mount base_command = @ports.reduce(base_command, &->(x, y) { x + " -p #{y}:#{y}" }) base_command += " -e CI=TRUE --name #{@container_name}" proc do |name| pretty_print(custom_message: "running #{name}") { call_system("#{base_command} #{name}") } end end |
#run ⇒ Boolean
if the last commit was a build commit try to load and run the image otherwise pull and run the upstream image
in prepare_run_func always:
1. run in detached mode with stdin open (-id)
2. pass CI=true to as a build argument
3. set the container name (pipeline-container)
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/nli_pipeline/docker_manager.rb', line 145 def run run_func = prepare_run_func # if the last commit had a build instruction, load the built image if build_commit? && @image_name load run_func.call(@image_name) # otherwise try to pull the upstream image from dockerhub elsif @upstream_image_name run_func.call(@upstream_image_name) # if neither image nor upstream image were set, throw config error # can't use raise_unless_all since some, but not all, must be set else = 'you must set image_name or upstream_image_name to run a docker image' config_error = "Config Error: #{}" config = { image_name: @image_name, upstream_image_name: @upstream_image_name, build_commit: build_commit? } raise SystemWrapper::ConfigError.new(config: config, msg: config_error) end end |
#save ⇒ Boolean
save docker image as tarfile
104 105 106 107 108 109 110 |
# File 'lib/nli_pipeline/docker_manager.rb', line 104 def save # throw an error is image_name is not set raise_unless_all(image_name: @image_name) save_command = "docker save #{@image_name} -o #{@path}/#{@tar_name}" puts 'saving docker image'.yellow pretty_print(custom_message: 'saved docker image') { call_system(save_command) } end |