kamaze-docker_image 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +6 -0
- data/.yardopts +16 -0
- data/lib/kamaze-docker_image.rb +24 -0
- data/lib/kamaze/docker_image.rb +223 -0
- data/lib/kamaze/docker_image/command.rb +79 -0
- data/lib/kamaze/docker_image/concern.rb +22 -0
- data/lib/kamaze/docker_image/concern/containers.rb +75 -0
- data/lib/kamaze/docker_image/concern/docker.rb +36 -0
- data/lib/kamaze/docker_image/concern/executable.rb +24 -0
- data/lib/kamaze/docker_image/concern/readable_attrs.rb +48 -0
- data/lib/kamaze/docker_image/concern/setup.rb +98 -0
- data/lib/kamaze/docker_image/concern/setup/config.rb +35 -0
- data/lib/kamaze/docker_image/loader.rb +61 -0
- data/lib/kamaze/docker_image/loader/context.rb +57 -0
- data/lib/kamaze/docker_image/loader/helper.rb +99 -0
- data/lib/kamaze/docker_image/loader/tasks.rb +22 -0
- data/lib/kamaze/docker_image/loader/tasks/build.rb +23 -0
- data/lib/kamaze/docker_image/loader/tasks/exec.rb +19 -0
- data/lib/kamaze/docker_image/loader/tasks/push.rb +19 -0
- data/lib/kamaze/docker_image/loader/tasks/restart.rb +21 -0
- data/lib/kamaze/docker_image/loader/tasks/run.rb +19 -0
- data/lib/kamaze/docker_image/loader/tasks/ssh.rb +19 -0
- data/lib/kamaze/docker_image/loader/tasks/start.rb +19 -0
- data/lib/kamaze/docker_image/loader/tasks/stop.rb +19 -0
- data/lib/kamaze/docker_image/runner.rb +126 -0
- data/lib/kamaze/docker_image/runner/storage.rb +78 -0
- data/lib/kamaze/docker_image/ssh.rb +143 -0
- data/lib/kamaze/docker_image/version.rb +13 -0
- data/lib/kamaze/docker_image/version.yml +17 -0
- metadata +99 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017-2021 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require_relative '../concern'
|
10
|
+
|
11
|
+
# Provides setup (used during initialization) and related methods.
|
12
|
+
#
|
13
|
+
# @todo remove this file, it SHOULD be useless
|
14
|
+
module Kamaze::DockerImage::Concern::Docker
|
15
|
+
autoload(:Docker, 'docker')
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
# Fetch containers
|
20
|
+
#
|
21
|
+
# @param [String] run_as
|
22
|
+
# @param [Array|nil] states
|
23
|
+
# @return [Array<Docker::Container>]
|
24
|
+
def fetch_containers(run_as, states = nil)
|
25
|
+
unless states.nil?
|
26
|
+
states = (states.is_a?(Array) ? states : [states]).map(&:to_s)
|
27
|
+
states = nil if states.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
Docker::Container.all(all: true).keep_if do |c|
|
31
|
+
states.to_a.empty? ? true : states.include?(c.info.fetch('State'))
|
32
|
+
end.keep_if do |c|
|
33
|
+
c.info.fetch('Names').include?("/#{run_as}")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017-2021 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require_relative '../concern'
|
10
|
+
|
11
|
+
# PProvide method to retrieve path to docker executable.
|
12
|
+
module Kamaze::DockerImage::Concern::Executable
|
13
|
+
autoload(:Cliver, 'cliver')
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
# Get executable
|
18
|
+
#
|
19
|
+
# @raise [Cliver::Dependency::NotFound]
|
20
|
+
# @return [String]
|
21
|
+
def executable
|
22
|
+
Cliver.detect!(:docker).freeze
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017-2021 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require_relative '../concern'
|
10
|
+
|
11
|
+
# Provides ``readable_attrs`` method
|
12
|
+
#
|
13
|
+
# Readable attributes have an instance variable and an accessor,
|
14
|
+
# boolean accessors are also supported.
|
15
|
+
#
|
16
|
+
# As a result, class including this module obtains a Hash representation.
|
17
|
+
module Kamaze::DockerImage::Concern::ReadableAttrs
|
18
|
+
# Get readable attributes
|
19
|
+
#
|
20
|
+
# @return [Array<Symbol>]
|
21
|
+
def readable_attrs
|
22
|
+
instance_variables.clone.map do |attr|
|
23
|
+
k = attr.to_s.gsub(/^@/, '').to_sym
|
24
|
+
|
25
|
+
methods = ([k, "#{k}?".to_sym] & public_methods)
|
26
|
+
|
27
|
+
methods.empty? ? nil : k
|
28
|
+
end.compact.sort
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_h
|
32
|
+
readable_attrs_values.to_h
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
# Get readable attributes with values
|
38
|
+
#
|
39
|
+
# @return [Array<Array>]
|
40
|
+
def readable_attrs_values
|
41
|
+
readable_attrs.map do |k|
|
42
|
+
# booleanaccessor will override "real" accessor
|
43
|
+
([k, "#{k}?".to_sym] & public_methods)
|
44
|
+
.map { |m| [k, self.public_send(m)] }
|
45
|
+
.first
|
46
|
+
end.compact
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017-2021 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require_relative '../concern'
|
10
|
+
|
11
|
+
# Provides setup (used during initialization) and related methods.
|
12
|
+
module Kamaze::DockerImage::Concern::Setup
|
13
|
+
autoload :OpenStruct, 'ostruct'
|
14
|
+
autoload :Pathname, 'pathname'
|
15
|
+
autoload :YAML, 'yaml'
|
16
|
+
autoload :Config, "#{__dir__}/setup/config"
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
# Setup
|
21
|
+
#
|
22
|
+
# @param [Array<Thread::Backtrace::Location>] locations
|
23
|
+
# @return [self]
|
24
|
+
def setup(locations, &block)
|
25
|
+
setup_defaults(locations).tap do
|
26
|
+
setup_block(&block)
|
27
|
+
|
28
|
+
@name = @name.to_s
|
29
|
+
@commands = Hash[@commands.map { |k, v| [k.to_sym, v] }]
|
30
|
+
|
31
|
+
to_h.each { |k, v| instance_variable_set("@#{k}", v) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# rubocop:disable Metrics/MethodLength
|
36
|
+
|
37
|
+
# Setup atttributes with default values
|
38
|
+
#
|
39
|
+
# @param [Array<Thread::Backtrace::Location>] locations
|
40
|
+
# @return [self]
|
41
|
+
def setup_defaults(locations)
|
42
|
+
self.tap do
|
43
|
+
@name = nil
|
44
|
+
@version = 'latest'
|
45
|
+
|
46
|
+
@path = Pathname.new('.')
|
47
|
+
@verbose = $stdout.tty? && $stderr.tty?
|
48
|
+
@tasks_load = true
|
49
|
+
@tasks_ns = nil
|
50
|
+
@run_as = called_from(locations).dirname.basename.to_s
|
51
|
+
@docker_bin = 'docker'
|
52
|
+
@exec_command = 'bash -il'
|
53
|
+
@commands = default_commands
|
54
|
+
@ssh = {}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# rubocop:enable Metrics/MethodLength
|
59
|
+
|
60
|
+
# @yield [Config] config used to setup instance
|
61
|
+
# @return [Config]
|
62
|
+
def setup_block
|
63
|
+
Config.new(self.respond_to?(:to_h) ? to_h : {}).tap do |s|
|
64
|
+
yield(s) if block_given?
|
65
|
+
|
66
|
+
s.freeze
|
67
|
+
s.to_h.each { |k, v| setup_attr(k, v) }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Get default commands
|
72
|
+
#
|
73
|
+
# @return [Hash]
|
74
|
+
def default_commands
|
75
|
+
content = Pathname.new(__dir__).join('..', 'commands.yml').read
|
76
|
+
|
77
|
+
YAML.safe_load(content, [Symbol])
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# Set given attr with given value
|
83
|
+
#
|
84
|
+
# @param [String|Symbol] attr
|
85
|
+
# @param [Object] val
|
86
|
+
def setup_attr(attr, val)
|
87
|
+
__send__("#{attr}=", val)
|
88
|
+
rescue NoMethodError
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
|
92
|
+
# @return [Pathname]
|
93
|
+
def called_from(locations = caller_locations)
|
94
|
+
location = locations.first.path
|
95
|
+
|
96
|
+
Pathname.new(location).realpath
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017-2021 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require_relative '../setup'
|
10
|
+
require 'ostruct'
|
11
|
+
|
12
|
+
# Config data structure
|
13
|
+
#
|
14
|
+
# @see https://ruby-doc.org/stdlib-2.0.0/libdoc/ostruct/rdoc/OpenStruct.html
|
15
|
+
class Kamaze::DockerImage::Concern::Setup::Config < OpenStruct
|
16
|
+
def respond_to_missing?(method, include_private = false)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
# Introduces some strictness on ``OpenStruct#method_missing``
|
21
|
+
#
|
22
|
+
# @see https://apidock.com/ruby/OpenStruct/method_missing
|
23
|
+
# @return [Object]
|
24
|
+
def method_missing(method, *args)
|
25
|
+
if method[-1] != '='
|
26
|
+
unless self.to_h.include?(method.to_sym)
|
27
|
+
message = "undefined method `#{method}' for #{self}"
|
28
|
+
|
29
|
+
raise NoMethodError, message, caller(1)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017-2021 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require_relative '../docker_image'
|
10
|
+
|
11
|
+
# Loader for tasks (using eval binding)
|
12
|
+
class Kamaze::DockerImage::Loader
|
13
|
+
autoload :Pathname, 'pathname'
|
14
|
+
autoload :Context, "#{__dir__}/loader/context"
|
15
|
+
|
16
|
+
# @param [Kamaze::DockerImage] image
|
17
|
+
def initialize(image)
|
18
|
+
@image = image.clone.freeze
|
19
|
+
end
|
20
|
+
|
21
|
+
# Load tasks.
|
22
|
+
#
|
23
|
+
# @return [self]
|
24
|
+
def call
|
25
|
+
self.tap do
|
26
|
+
if loadable?
|
27
|
+
context.call do |b|
|
28
|
+
b.local_variable_set(:image, image)
|
29
|
+
b.eval(content)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Boolean]
|
36
|
+
def loadable?
|
37
|
+
context.dsl?
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
# @return [Kamaze::DockerImage]
|
43
|
+
attr_reader :image
|
44
|
+
|
45
|
+
# @return [Pathname]
|
46
|
+
def file
|
47
|
+
Pathname.new(__dir__).join('loader', 'tasks.rb')
|
48
|
+
end
|
49
|
+
|
50
|
+
# Tasks file content (to eval)
|
51
|
+
#
|
52
|
+
# @return [String]
|
53
|
+
def content
|
54
|
+
file.read
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Module<Context>]
|
58
|
+
def context
|
59
|
+
Context
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017-2021 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require_relative '../loader'
|
10
|
+
|
11
|
+
# Provides empty binding.
|
12
|
+
#
|
13
|
+
# Sample of use:
|
14
|
+
#
|
15
|
+
# ```ruby
|
16
|
+
# Context.call do |b|
|
17
|
+
# b.local_variable_set(:answer, 42)
|
18
|
+
# b.local_variable_set(:home, '127.0.0.1')
|
19
|
+
#
|
20
|
+
# b.eval(content)
|
21
|
+
# end
|
22
|
+
# ```
|
23
|
+
module Kamaze::DockerImage::Loader::Context
|
24
|
+
class << self
|
25
|
+
def call
|
26
|
+
yield(binding)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Denote ``DSL`` is defined.
|
30
|
+
#
|
31
|
+
# @return [Boolean]
|
32
|
+
def dsl?
|
33
|
+
!!dsl
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
# @return [Binding]
|
39
|
+
def binding
|
40
|
+
-> { super }.tap { load_dsl }.call
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Rake::DSL, nil]
|
44
|
+
def dsl
|
45
|
+
Object.const_get('Rake::DSL')
|
46
|
+
rescue NameError
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
# Apply ``Rake::DSL``
|
51
|
+
#
|
52
|
+
# @return [self]
|
53
|
+
def load_dsl
|
54
|
+
self.tap { self.extend(dsl) if dsl? }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017-2021 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require_relative '../loader'
|
10
|
+
|
11
|
+
# Helper for tasks.
|
12
|
+
#
|
13
|
+
# Sample of use:
|
14
|
+
#
|
15
|
+
# ```ruby
|
16
|
+
# helper = Kamaze::DockerImage::Loader::Helper.new(image)
|
17
|
+
#
|
18
|
+
# desc 'Run a command in a new container'
|
19
|
+
#
|
20
|
+
# task helper.appoint(:run), [:command] do |task, args|
|
21
|
+
# helper.call(task, args) { image.run(args[:command]) }
|
22
|
+
# end
|
23
|
+
# ````
|
24
|
+
class Kamaze::DockerImage::Loader::Helper
|
25
|
+
# @param [Kamaze::DockerImage] image
|
26
|
+
def initialize(image)
|
27
|
+
@image = image
|
28
|
+
end
|
29
|
+
|
30
|
+
# Make task name using namespace (from image)
|
31
|
+
#
|
32
|
+
# @return [String]
|
33
|
+
def appoint(name)
|
34
|
+
namer.call(name)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Execute related ``pre_`` and ``post_`` tasks
|
38
|
+
#
|
39
|
+
# @param [Rake::Task] task
|
40
|
+
# @param [Hash{Symbol => Object}] args
|
41
|
+
#
|
42
|
+
# Sample of use:
|
43
|
+
#
|
44
|
+
# ```ruby
|
45
|
+
# task 'docker:pre_start' do |task, args|
|
46
|
+
# pp(task, args)
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# task 'docker:post_start' do |task, args|
|
50
|
+
# pp(task, args)
|
51
|
+
# end
|
52
|
+
# ```
|
53
|
+
def wrap(task, args = [], &block)
|
54
|
+
on_pre(task, args)
|
55
|
+
block.call
|
56
|
+
on_post(task, args)
|
57
|
+
end
|
58
|
+
|
59
|
+
alias call wrap
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
# @return [Kamaze::DockerImage]
|
64
|
+
attr_accessor :image
|
65
|
+
|
66
|
+
# @return [Proc]
|
67
|
+
def namer
|
68
|
+
lambda do |name|
|
69
|
+
"#{image.tasks_ns}:#{name}".gsub(/^:/, '')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# @param [Rake::Task] task
|
74
|
+
def on_pre(task, args)
|
75
|
+
task_call(on: :pre, from: task, args: args)
|
76
|
+
end
|
77
|
+
|
78
|
+
# @param [Rake::Task] task
|
79
|
+
def on_post(task, args)
|
80
|
+
task_call(on: :post, from: task, args: args)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Call pre/post tasks.
|
84
|
+
#
|
85
|
+
# on: pre/post
|
86
|
+
# from: task as ``Rake::Task``
|
87
|
+
# args: Hash
|
88
|
+
def task_call(on:, from:, args:)
|
89
|
+
cname = from.name.gsub(/^#{image.tasks_ns}:/, '')
|
90
|
+
# @formatter:off
|
91
|
+
{
|
92
|
+
pre: namer.call("pre_#{cname}"),
|
93
|
+
post: namer.call("post_#{cname}"),
|
94
|
+
}.fetch(on).tap do |name|
|
95
|
+
Rake::Task[name].execute(**args.to_h) if Rake::Task.task_defined?(name)
|
96
|
+
end
|
97
|
+
# @formatter:on
|
98
|
+
end
|
99
|
+
end
|