Module: Dklet::DSL
- Defined in:
- lib/dklet/dsl.rb
Class Method Summary collapse
Instance Method Summary collapse
- #add_dsl(&blk) ⇒ Object
- #add_note(str) ⇒ Object
-
#app_release ⇒ Object
标识一次运行发布的用途, 如redis for hirails-only.
- #app_tags ⇒ Object
- #appname ⇒ Object
- #approot ⇒ Object
- #before_task(name = :main, &blk) ⇒ Object
- #build_net ⇒ Object
- #build_root ⇒ Object
-
#compose_cmd ⇒ Object
-f, –file -p, –project-name to altertive project name, eg.
-
#compose_name ⇒ Object
project name for docker-compose.
- #container_filters_for_release ⇒ Object
- #container_missing ⇒ Object
-
#containers_for_image(img = docker_image) ⇒ Object
Note: if img1:t1 = img2:t2 points to same image hashid, they will be selected as same.
- #containers_for_release ⇒ Object
- #containers_in_net(net = netname) ⇒ Object
- #custom_commands(&blk) ⇒ Object
- #default_app_volumes ⇒ Object
- #default_container_name ⇒ Object
-
#default_docker_image ⇒ Object
release is not relevant.
- #default_image_labels ⇒ Object
- #default_image_tag ⇒ Object
- #default_ops_container ⇒ Object
- #disable(key) ⇒ Object
- #disabled?(key) ⇒ Boolean
-
#dklet_config_for(name) ⇒ Object
todo.
- #dklet_script ⇒ Object
-
#dkrun_cmd(labeled: true, opts: nil, named: false) ⇒ Object
maybe from external image.
- #dktmprun(opts: nil) ⇒ Object
- #dockerfile ⇒ Object
- #dsl_methods ⇒ Object
- #ensure_docker_net(name, driver: :bridge) ⇒ Object
- #env ⇒ Object
- #fetch(key) ⇒ Object
- #fetch_with_default(key) ⇒ Object
- #file_content_for(name) ⇒ Object
- #file_for(name) ⇒ Object
-
#find_net(name) ⇒ Object
use label (not name) filter to avoid str part match.
-
#full_release_name ⇒ Object
take into acccount: app, env, app_release.
-
#host_domain_in_container ⇒ Object
ref dklet/mac/hostnet.
- #host_port_for(cport) ⇒ Object
-
#host_with_port_for(cport, host_ip: true, only_port: false) ⇒ Object
0.0.0.0:32879.
- #in_dev? ⇒ Boolean
- #in_prod? ⇒ Boolean
- #label_key(key, prefix: true) ⇒ Object
-
#label_pair(key, val, prefix: true) ⇒ Object
key=value pair.
- #let_cli_magic_start! ⇒ Object
- #netname ⇒ Object
-
#proxy_domain_base ⇒ Object
top proxy domain part.
- #proxy_domains(*doms) ⇒ Object
- #raw_dockerfile ⇒ Object
- #raw_specfile ⇒ Object
- #register(key, value) ⇒ Object
- #register_app_tag(tag) ⇒ Object
- #register_approot(path) ⇒ Object
- #register_build_net(net) ⇒ Object
- #register_build_root(path) ⇒ Object
- #register_default_env(str) ⇒ Object
- #register_docker_image(name) ⇒ Object
-
#register_domain(*doms) ⇒ Object
domain.
-
#register_net(name = :dailyops, build: false) ⇒ Object
docker networking.
- #register_ops(cid) ⇒ Object
- #register_path(key, path) ⇒ Object
- #registry ⇒ Object
- #release_label_hash ⇒ Object
-
#release_path_name ⇒ Object
make path friendly.
- #rendered_file_for(name, locals: {}, in_binding: binding) ⇒ Object
-
#script_name ⇒ Object
use <parent_path_name>_<script_file_name> to ensure possible unique.
-
#script_path ⇒ Object
触发脚本所在(绝对)路径.
- #set_file_for(name, str) ⇒ Object
- #smart_build_context_path ⇒ Object
-
#specfile ⇒ Object
rendered in current context.
-
#task(name = :main, opts = {}, &blk) ⇒ Object
main dsl.
- #task_opts(name = :main) ⇒ Object
- #tmpfile_for(str) ⇒ Object
- #user_notes ⇒ Object
- #volumes_root ⇒ Object
-
#write_dockerfile(str, path: nil) ⇒ Object
Dockerfile for image build.
-
#write_specfile(str) ⇒ Object
specfile for k8s resources spec manifest.
Class Method Details
.dsl_method(mthd) ⇒ Object
11 12 13 14 15 16 |
# File 'lib/dklet/dsl.rb', line 11 def dsl_method(mthd) dsl_methods << mthd define_method(mthd) do fetch_with_default(mthd) end end |
.dsl_methods ⇒ Object
7 8 9 |
# File 'lib/dklet/dsl.rb', line 7 def dsl_methods @_dsl_methods ||= [] end |
.registry ⇒ Object
3 4 5 |
# File 'lib/dklet/dsl.rb', line 3 def registry @_registry ||= {} end |
Instance Method Details
#add_dsl(&blk) ⇒ Object
23 24 25 |
# File 'lib/dklet/dsl.rb', line 23 def add_dsl &blk Dklet::DSL.module_eval &blk end |
#add_note(str) ⇒ Object
226 227 228 |
# File 'lib/dklet/dsl.rb', line 226 def add_note str (registry[:user_notes] ||= []) << str end |
#app_release ⇒ Object
标识一次运行发布的用途, 如redis for hirails-only
373 374 375 |
# File 'lib/dklet/dsl.rb', line 373 def app_release ENV['APP_RELEASE'] || 'default' end |
#app_tags ⇒ Object
306 307 308 |
# File 'lib/dklet/dsl.rb', line 306 def registry[:app_tags] ||= [] end |
#appname ⇒ Object
288 289 290 |
# File 'lib/dklet/dsl.rb', line 288 def appname fetch(:appname) || script_name end |
#approot ⇒ Object
284 285 286 |
# File 'lib/dklet/dsl.rb', line 284 def approot fetch(:approot) || build_root || script_path end |
#before_task(name = :main, &blk) ⇒ Object
209 210 211 |
# File 'lib/dklet/dsl.rb', line 209 def before_task(name = :main, &blk) task(name, type: :before, &blk) end |
#build_net ⇒ Object
331 332 333 |
# File 'lib/dklet/dsl.rb', line 331 def build_net fetch(:build_net) end |
#build_root ⇒ Object
323 324 325 |
# File 'lib/dklet/dsl.rb', line 323 def build_root fetch(:build_root) end |
#compose_cmd ⇒ Object
-f, –file -p, –project-name to altertive project name, eg. default net prefix
276 277 278 |
# File 'lib/dklet/dsl.rb', line 276 def compose_cmd "docker-compose -f #{specfile} --project-name #{compose_name} --project-directory #{approot}" end |
#compose_name ⇒ Object
project name for docker-compose
270 271 272 |
# File 'lib/dklet/dsl.rb', line 270 def compose_name "#{fetch(:compose_name) || appname}_#{env}" end |
#container_filters_for_release ⇒ Object
95 96 97 98 99 |
# File 'lib/dklet/dsl.rb', line 95 def container_filters_for_release release_label_hash.map do |k, v| "--filter label=#{k}=#{v}" end.join(' ') end |
#container_missing ⇒ Object
352 353 354 |
# File 'lib/dklet/dsl.rb', line 352 def container_missing puts "Not found container for image: #{docker_image}" end |
#containers_for_image(img = docker_image) ⇒ Object
Note: if img1:t1 = img2:t2 points to same image hashid, they will be selected as same
106 107 108 |
# File 'lib/dklet/dsl.rb', line 106 def containers_for_image(img = docker_image) `docker ps -aq -f ancestor=#{img}`.split("\n") end |
#containers_for_release ⇒ Object
101 102 103 |
# File 'lib/dklet/dsl.rb', line 101 def containers_for_release `docker ps -aq #{container_filters_for_release}`.split("\n") end |
#containers_in_net(net = netname) ⇒ Object
110 111 112 |
# File 'lib/dklet/dsl.rb', line 110 def containers_in_net(net = netname) `docker ps -aq -f network=#{net}`.split("\n") end |
#custom_commands(&blk) ⇒ Object
222 223 224 |
# File 'lib/dklet/dsl.rb', line 222 def custom_commands &blk DockletCLI.class_eval &blk end |
#default_app_volumes ⇒ Object
390 391 392 |
# File 'lib/dklet/dsl.rb', line 390 def default_app_volumes volumes_root.join(release_path_name) end |
#default_container_name ⇒ Object
348 349 350 |
# File 'lib/dklet/dsl.rb', line 348 def default_container_name full_release_name end |
#default_docker_image ⇒ Object
release is not relevant
55 56 57 |
# File 'lib/dklet/dsl.rb', line 55 def default_docker_image "#{env}/#{appname}:#{image_tag}" end |
#default_image_labels ⇒ Object
63 64 65 |
# File 'lib/dklet/dsl.rb', line 63 def default_image_labels "maintainer=dailyops built_from=dklet" end |
#default_image_tag ⇒ Object
59 60 61 |
# File 'lib/dklet/dsl.rb', line 59 def default_image_tag "edge" end |
#default_ops_container ⇒ Object
344 345 346 |
# File 'lib/dklet/dsl.rb', line 344 def default_ops_container containers_for_release.first # || container_name end |
#disable(key) ⇒ Object
193 194 195 |
# File 'lib/dklet/dsl.rb', line 193 def disable(key) (registry[:disable] ||= {})[key] = true end |
#disabled?(key) ⇒ Boolean
197 198 199 |
# File 'lib/dklet/dsl.rb', line 197 def disabled?(key) (registry[:disable] ||= {})[key] end |
#dklet_config_for(name) ⇒ Object
todo
151 152 153 154 155 |
# File 'lib/dklet/dsl.rb', line 151 def dklet_config_for(name) p = Pathname("/dkconf/#{full_release_name}") p.mkpath unless p.directory? p.join(name) end |
#dklet_script ⇒ Object
114 115 116 |
# File 'lib/dklet/dsl.rb', line 114 def dklet_script Pathname($PROGRAM_NAME) end |
#dkrun_cmd(labeled: true, opts: nil, named: false) ⇒ Object
maybe from external image
76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/dklet/dsl.rb', line 76 def dkrun_cmd(labeled: true, opts: nil, named: false) cmd = "docker run" if labeled release_labels = release_label_hash.map do |k, v| "--label=#{k}=#{v}" end.join(' ') cmd += " #{release_labels}" end cmd += " --net #{netname}" if netname cmd += " --name #{container_name}" if named cmd += " #{opts}" if opts cmd end |
#dktmprun(opts: nil) ⇒ Object
90 91 92 93 |
# File 'lib/dklet/dsl.rb', line 90 def dktmprun(opts: nil) cmd = dkrun_cmd(opts: "--rm -i #{opts}", labeled: false) "#{cmd} #{docker_image}" end |
#dockerfile ⇒ Object
175 176 177 |
# File 'lib/dklet/dsl.rb', line 175 def dockerfile rendered_file_for(:dockerfile) end |
#dsl_methods ⇒ Object
27 28 29 |
# File 'lib/dklet/dsl.rb', line 27 def dsl_methods Dklet::DSL.dsl_methods end |
#ensure_docker_net(name, driver: :bridge) ⇒ Object
244 245 246 247 248 249 250 |
# File 'lib/dklet/dsl.rb', line 244 def ensure_docker_net(name, driver: :bridge) unless netid = find_net(name) puts "create new network: #{name}" netid = `docker network create #{name} --label #{label_pair(:name, name)} --driver=#{driver}` end netid end |
#env ⇒ Object
360 361 362 |
# File 'lib/dklet/dsl.rb', line 360 def env ENV['APP_ENV'] || fetch(:default_env) || 'dev' end |
#fetch(key) ⇒ Object
35 36 37 38 39 40 41 |
# File 'lib/dklet/dsl.rb', line 35 def fetch(key) val = registry[key] if val && val.respond_to?(:call) val = val.call end val end |
#fetch_with_default(key) ⇒ Object
43 44 45 46 47 48 |
# File 'lib/dklet/dsl.rb', line 43 def fetch_with_default(key) provided = fetch(key) return provided if provided mthd = "default_#{key}" send(mthd) if respond_to?(mthd) end |
#file_content_for(name) ⇒ Object
144 145 146 147 148 |
# File 'lib/dklet/dsl.rb', line 144 def file_content_for(name) fpath = fetch(name) return unless fpath File.read(fpath) end |
#file_for(name) ⇒ Object
140 141 142 |
# File 'lib/dklet/dsl.rb', line 140 def file_for(name) fetch(name) end |
#find_net(name) ⇒ Object
use label (not name) filter to avoid str part match
253 254 255 256 257 258 |
# File 'lib/dklet/dsl.rb', line 253 def find_net(name) cmd = "docker network ls -q --filter label=#{label_pair(:name, name)}" netid = `#{cmd}`.chomp return netid unless netid.empty? nil end |
#full_release_name ⇒ Object
take into acccount: app, env, app_release
293 294 295 |
# File 'lib/dklet/dsl.rb', line 293 def full_release_name [env, appname, app_release].compact.join('_') end |
#host_domain_in_container ⇒ Object
ref dklet/mac/hostnet
419 420 421 |
# File 'lib/dklet/dsl.rb', line 419 def host_domain_in_container ENV['HOST_DOMAIN_IN_CONTAINER'] || 'host.dokcer.internal' end |
#host_port_for(cport) ⇒ Object
434 435 436 |
# File 'lib/dklet/dsl.rb', line 434 def host_port_for(cport) host_with_port_for(cport, only_port: true) end |
#host_with_port_for(cport, host_ip: true, only_port: false) ⇒ Object
0.0.0.0:32879
424 425 426 427 428 429 430 431 432 |
# File 'lib/dklet/dsl.rb', line 424 def host_with_port_for(cport, host_ip: true, only_port: false ) str = `docker port #{ops_container} #{cport}`.chomp return if str.empty? if only_port return str.split(':').last end return str unless host_ip str.sub('0.0.0.0', Dklet::Util.host_ip) end |
#in_dev? ⇒ Boolean
364 365 366 |
# File 'lib/dklet/dsl.rb', line 364 def in_dev? env =~ /^dev/ end |
#in_prod? ⇒ Boolean
368 369 370 |
# File 'lib/dklet/dsl.rb', line 368 def in_prod? env =~ /^prod/ end |
#label_key(key, prefix: true) ⇒ Object
260 261 262 |
# File 'lib/dklet/dsl.rb', line 260 def label_key(key, prefix: true) prefix ? "docklet.#{key}" : key end |
#label_pair(key, val, prefix: true) ⇒ Object
key=value pair
265 266 267 |
# File 'lib/dklet/dsl.rb', line 265 def label_pair(key, val, prefix: true) [label_key(key, prefix: prefix), val].join('=') end |
#let_cli_magic_start! ⇒ Object
218 219 220 |
# File 'lib/dklet/dsl.rb', line 218 def let_cli_magic_start! DockletCLI.start end |
#netname ⇒ Object
240 241 242 |
# File 'lib/dklet/dsl.rb', line 240 def netname fetch(:netname) end |
#proxy_domain_base ⇒ Object
top proxy domain part
400 401 402 |
# File 'lib/dklet/dsl.rb', line 400 def proxy_domain_base ENV['PROXY_DOMAIN_BASE'] || 'lh' end |
#proxy_domains(*doms) ⇒ Object
404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/dklet/dsl.rb', line 404 def proxy_domains(*doms) if doms.empty? doms = fetch(:domains) doms = [appname] if doms.nil? or doms.empty? end denv = env denv = nil if denv =~ /^prod/ doms.map do |d| [d, denv, proxy_domain_base].compact.join('.') end.join(',') end |
#raw_dockerfile ⇒ Object
171 172 173 |
# File 'lib/dklet/dsl.rb', line 171 def raw_dockerfile fetch(:dockerfile) end |
#raw_specfile ⇒ Object
184 185 186 |
# File 'lib/dklet/dsl.rb', line 184 def raw_specfile fetch(:specfile) end |
#register(key, value) ⇒ Object
31 32 33 |
# File 'lib/dklet/dsl.rb', line 31 def register(key, value) registry[key] = value end |
#register_app_tag(tag) ⇒ Object
302 303 304 |
# File 'lib/dklet/dsl.rb', line 302 def register_app_tag(tag) << tag end |
#register_approot(path) ⇒ Object
280 281 282 |
# File 'lib/dklet/dsl.rb', line 280 def register_approot path register_path(:approot, path) end |
#register_build_net(net) ⇒ Object
327 328 329 |
# File 'lib/dklet/dsl.rb', line 327 def register_build_net net register(:build_net, net) end |
#register_build_root(path) ⇒ Object
319 320 321 |
# File 'lib/dklet/dsl.rb', line 319 def register_build_root path register_path(:build_root, path) end |
#register_default_env(str) ⇒ Object
356 357 358 |
# File 'lib/dklet/dsl.rb', line 356 def register_default_env(str) register :default_env, str end |
#register_docker_image(name) ⇒ Object
50 51 52 |
# File 'lib/dklet/dsl.rb', line 50 def register_docker_image(name) register :docker_image, name end |
#register_domain(*doms) ⇒ Object
domain
395 396 397 |
# File 'lib/dklet/dsl.rb', line 395 def register_domain(*doms) register :domains, doms end |
#register_net(name = :dailyops, build: false) ⇒ Object
docker networking
235 236 237 238 |
# File 'lib/dklet/dsl.rb', line 235 def register_net(name = :dailyops, build: false) register :netname, name ensure_docker_net(name) if build end |
#register_ops(cid) ⇒ Object
340 341 342 |
# File 'lib/dklet/dsl.rb', line 340 def register_ops(cid) register :ops_container, cid end |
#register_path(key, path) ⇒ Object
335 336 337 338 |
# File 'lib/dklet/dsl.rb', line 335 def register_path key, path path = Pathname(path) unless path.is_a?(Pathname) register key, path end |
#release_label_hash ⇒ Object
67 68 69 70 71 72 73 |
# File 'lib/dklet/dsl.rb', line 67 def release_label_hash { dklet_env: env, dklet_app: appname, dklet_release: app_release } end |
#release_path_name ⇒ Object
make path friendly
298 299 300 |
# File 'lib/dklet/dsl.rb', line 298 def release_path_name full_release_name.gsub(/_/, '-') end |
#rendered_file_for(name, locals: {}, in_binding: binding) ⇒ Object
157 158 159 160 161 162 163 |
# File 'lib/dklet/dsl.rb', line 157 def rendered_file_for(name, locals: {}, in_binding: binding) tmpl = file_content_for(name) return unless tmpl erb = ERB.new(tmpl, nil, '%<>') rendered = erb.result(in_binding) tmpfile_for(rendered) end |
#script_name ⇒ Object
use <parent_path_name>_<script_file_name> to ensure possible unique
124 125 126 127 128 129 130 |
# File 'lib/dklet/dsl.rb', line 124 def script_name # not file name sname = fetch(:script_name) return sname if sname name = dklet_script.basename('.rb').to_s pname = script_path.basename.to_s "#{pname}_#{name}" end |
#script_path ⇒ Object
触发脚本所在(绝对)路径
119 120 121 |
# File 'lib/dklet/dsl.rb', line 119 def script_path dklet_script.realdirpath.dirname end |
#set_file_for(name, str) ⇒ Object
136 137 138 |
# File 'lib/dklet/dsl.rb', line 136 def set_file_for(name, str) register name, tmpfile_for(str) end |
#smart_build_context_path ⇒ Object
310 311 312 313 314 315 316 317 |
# File 'lib/dklet/dsl.rb', line 310 def smart_build_context_path # use explicitly specified, maybe nil return build_root if registry.has_key?(:build_root) # check build path dependent body = File.read(dockerfile) need_path = body =~ /^\s*(ADD|COPY)\s/i script_path if need_path end |
#specfile ⇒ Object
rendered in current context
189 190 191 |
# File 'lib/dklet/dsl.rb', line 189 def specfile rendered_file_for(:specfile) end |
#task(name = :main, opts = {}, &blk) ⇒ Object
main dsl
202 203 204 205 206 207 |
# File 'lib/dklet/dsl.rb', line 202 def task(name = :main, opts={}, &blk) type = opts.delete(:type) || :after hooks_name = "#{name}_#{type}_hooks".to_sym (registry[hooks_name] ||= []) << blk task_opts(name).merge!(opts) unless opts.empty? end |
#task_opts(name = :main) ⇒ Object
213 214 215 216 |
# File 'lib/dklet/dsl.rb', line 213 def task_opts(name = :main) key = "opts_for_task_#{name}".to_sym registry[key] ||= {} end |
#tmpfile_for(str) ⇒ Object
132 133 134 |
# File 'lib/dklet/dsl.rb', line 132 def tmpfile_for(str) Dklet::Util.tmpfile_for(str) end |
#user_notes ⇒ Object
230 231 232 |
# File 'lib/dklet/dsl.rb', line 230 def user_notes fetch(:user_notes) end |
#volumes_root ⇒ Object
377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/dklet/dsl.rb', line 377 def volumes_root vols_root = "#{ENV['HOME']}/DockerVolumes" root = fetch(:volumes_root) || if File.directory?(vols_root) # friendly to File sharing on Docker for Mac vols_root else '~/docker-volumes' end proot = Pathname(root) proot.mkpath unless proot.directory? proot end |
#write_dockerfile(str, path: nil) ⇒ Object
Dockerfile for image build
166 167 168 169 |
# File 'lib/dklet/dsl.rb', line 166 def write_dockerfile(str, path: nil) set_file_for(:dockerfile, str) register_build_root(path) if path end |
#write_specfile(str) ⇒ Object
specfile for k8s resources spec manifest
180 181 182 |
# File 'lib/dklet/dsl.rb', line 180 def write_specfile(str) set_file_for(:specfile, str) end |