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
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: fad5772cb626cf0f9a7be4b64b3c5f32dd14daff83f8eccc6345e22d5120b8aa
         | 
| 4 | 
            +
              data.tar.gz: ae5b2cfd9b17dba7827f5e7d88763c6bee9e24dc55b6f567661fb147b0e1f89d
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 073c70b2161a1d37569e3fe44ff94447a8219f31bae85518d97e59a9c098569c9d75739c3d3c427c6cf506d51a1125cb5e3230669071e874a565955be0e87893
         | 
| 7 | 
            +
              data.tar.gz: 7f2c5d696672fdb98f8d696ebb5185ed1b0df1bd695b99277bfc27922635b3da522ec29aeefdde1d7798f0c49828220f63cf70bd73e2af7166f9ab668a1232b4
         | 
    
        data/.rubocop.yml
    ADDED
    
    
    
        data/.yardopts
    ADDED
    
    | @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            # vim: ft=sh
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            lib/**/*.rb                                   \
         | 
| 4 | 
            +
                --no-progress                             \
         | 
| 5 | 
            +
                --markup-provider 'redcarpet'             \
         | 
| 6 | 
            +
                --markup 'markdown'                       \
         | 
| 7 | 
            +
                --charset 'utf-8'                         \
         | 
| 8 | 
            +
                --protected --private --embed-mixins      \
         | 
| 9 | 
            +
                --tag type:'type' --hide-tag 'type'       \
         | 
| 10 | 
            +
                --readme README.md                        \
         | 
| 11 | 
            +
                --exclude '_flymake\\.rb$'                \
         | 
| 12 | 
            +
                --exclude '/\\.#'
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            # Local Variables:
         | 
| 15 | 
            +
            # mode: sh
         | 
| 16 | 
            +
            # 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 | 
            +
            $LOAD_PATH.unshift(__dir__)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            lock = Dir.chdir("#{__dir__}/..") do
         | 
| 12 | 
            +
              [['gems.rb', 'gems.locked'], ['Gemfile', 'Gemfile.lock']]
         | 
| 13 | 
            +
                .map { |m| Dir.glob(m).size >= 2 }
         | 
| 14 | 
            +
                .include?(true)
         | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            if lock
         | 
| 18 | 
            +
              require 'rubygems'
         | 
| 19 | 
            +
              require 'bundler/setup'
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              if Gem::Specification.find_all_by_name('kamaze-project').any?
         | 
| 22 | 
            +
                require 'kamaze/project/core_ext/pp'
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,223 @@ | |
| 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 | 
            +
            # rubocop:disable Style/Documentation
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            module Kamaze
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            # rubocop:enable Style/Documentation
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            # Describe a docker image
         | 
| 17 | 
            +
            class Kamaze::DockerImage
         | 
| 18 | 
            +
              # Get commands
         | 
| 19 | 
            +
              #
         | 
| 20 | 
            +
              # Commands as run by runner
         | 
| 21 | 
            +
              #
         | 
| 22 | 
            +
              # @see Kamaze::DockerImage::Runner#command
         | 
| 23 | 
            +
              # @see Kamaze::DockerImage::Concern::Setup#default_commands
         | 
| 24 | 
            +
              #
         | 
| 25 | 
            +
              # @return [Hash]
         | 
| 26 | 
            +
              attr_reader :commands
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              # Get image name
         | 
| 29 | 
            +
              #
         | 
| 30 | 
            +
              # @return [String]
         | 
| 31 | 
            +
              attr_reader :name
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              # Get version
         | 
| 34 | 
            +
              #
         | 
| 35 | 
            +
              # @return [String]
         | 
| 36 | 
            +
              attr_reader :version
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              # Get namespace used for tasks
         | 
| 39 | 
            +
              #
         | 
| 40 | 
            +
              # @return [String|Symbol|nil]
         | 
| 41 | 
            +
              attr_reader :tasks_ns
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              # Get name used to run container
         | 
| 44 | 
            +
              #
         | 
| 45 | 
            +
              # @return [String]
         | 
| 46 | 
            +
              attr_reader :run_as
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              # Config related to ssh.
         | 
| 49 | 
            +
              #
         | 
| 50 | 
            +
              # @return [Hash|nil]
         | 
| 51 | 
            +
              attr_reader :ssh
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              # Executable path or name for ``docker``
         | 
| 54 | 
            +
              #
         | 
| 55 | 
            +
              # @return [String]
         | 
| 56 | 
            +
              attr_reader :docker_bin
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              attr_reader :tasks_load
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              # Get default command for ``exec``
         | 
| 61 | 
            +
              #
         | 
| 62 | 
            +
              # @see Runner#exec
         | 
| 63 | 
            +
              #
         | 
| 64 | 
            +
              # @return [String]
         | 
| 65 | 
            +
              attr_reader :exec_command
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              autoload(:Pathname, 'pathname')
         | 
| 68 | 
            +
              autoload(:Open3, 'open3')
         | 
| 69 | 
            +
              autoload(:JSON, 'json')
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              {
         | 
| 72 | 
            +
                Concern: 'concern',
         | 
| 73 | 
            +
                Command: 'command',
         | 
| 74 | 
            +
                Runner: 'runner',
         | 
| 75 | 
            +
                SSH: 'ssh',
         | 
| 76 | 
            +
                Loader: 'loader',
         | 
| 77 | 
            +
                VERSION: 'version',
         | 
| 78 | 
            +
              }.each { |k, v| autoload(k, "#{__dir__}/docker_image/#{v}") }
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              include Concern::Executable
         | 
| 81 | 
            +
              include Concern::Setup
         | 
| 82 | 
            +
              include Concern::ReadableAttrs
         | 
| 83 | 
            +
             | 
| 84 | 
            +
              def initialize(&block)
         | 
| 85 | 
            +
                setup(caller_locations, &block)
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                @runner = Runner.new(self)
         | 
| 88 | 
            +
                @ssh = SSH.new(self).freeze
         | 
| 89 | 
            +
                tasks_load! if tasks_load?
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
              # Get image id (through docker command).
         | 
| 93 | 
            +
              #
         | 
| 94 | 
            +
              # @return [String, nil]
         | 
| 95 | 
            +
              def id
         | 
| 96 | 
            +
                # docker image list --format "{{json .ID}}" image_name:image_version
         | 
| 97 | 
            +
                [
         | 
| 98 | 
            +
                  self.to_h[:docker_bin] || executable
         | 
| 99 | 
            +
                ].concat(['image', 'list', '--format', '{{json .ID}}', self.to_s]).yield_self do |command|
         | 
| 100 | 
            +
                  Open3.capture3(*command).tap do |stdout, _, status|
         | 
| 101 | 
            +
                    return nil unless status.success?
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                    return stdout.lines.empty? ? nil : JSON.parse(stdout.lines.first)
         | 
| 104 | 
            +
                  end
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
              end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
              # Denote image is started.
         | 
| 109 | 
            +
              #
         | 
| 110 | 
            +
              # @return [Boolean]
         | 
| 111 | 
            +
              def started?
         | 
| 112 | 
            +
                runner.started?
         | 
| 113 | 
            +
              end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              # Denote image is running?.
         | 
| 116 | 
            +
              #
         | 
| 117 | 
            +
              # @return [Boolean]
         | 
| 118 | 
            +
              def running?
         | 
| 119 | 
            +
                runner.running?
         | 
| 120 | 
            +
              end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
              # Get name of available commands.
         | 
| 123 | 
            +
              #
         | 
| 124 | 
            +
              # @return [Array<Symbol>]
         | 
| 125 | 
            +
              def available_commands
         | 
| 126 | 
            +
                commands.clone.reject { |_k, args| args.nil? }.to_h.keys.sort
         | 
| 127 | 
            +
              end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
              # Get tag
         | 
| 130 | 
            +
              #
         | 
| 131 | 
            +
              # tag has the following format: ``#{name}:#{version}``
         | 
| 132 | 
            +
              #
         | 
| 133 | 
            +
              # @return [String]
         | 
| 134 | 
            +
              def tag
         | 
| 135 | 
            +
                "#{name}:#{version}"
         | 
| 136 | 
            +
              end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
              alias to_s tag
         | 
| 139 | 
            +
             | 
| 140 | 
            +
              # @return [Hash]
         | 
| 141 | 
            +
              def to_h
         | 
| 142 | 
            +
                readable_attrs_values
         | 
| 143 | 
            +
                  .to_h.tap { |h| h.merge!(tag: tag) }
         | 
| 144 | 
            +
                  .sort.to_h
         | 
| 145 | 
            +
              end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
              # @return [Boolean]
         | 
| 148 | 
            +
              def verbose?
         | 
| 149 | 
            +
                !!@verbose
         | 
| 150 | 
            +
              end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
              # @return [Boolean]
         | 
| 153 | 
            +
              def tasks_load?
         | 
| 154 | 
            +
                !!self.tasks_load
         | 
| 155 | 
            +
              end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
              # @return [Pathname]
         | 
| 158 | 
            +
              def path
         | 
| 159 | 
            +
                Pathname.new(@path)
         | 
| 160 | 
            +
              end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
              # @see Runner#actions
         | 
| 163 | 
            +
              def method_missing(method, *args, &block)
         | 
| 164 | 
            +
                respond_to_missing?(method) ? runner.public_send(method, *args, &block) : super
         | 
| 165 | 
            +
              end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
              def respond_to_missing?(method, include_private = false)
         | 
| 168 | 
            +
                # rubocop:disable Style/RedundantParentheses
         | 
| 169 | 
            +
                (runner&.actions).to_a.include?(method.to_sym) || super(method, include_private)
         | 
| 170 | 
            +
                # rubocop:enable Style/RedundantParentheses
         | 
| 171 | 
            +
              end
         | 
| 172 | 
            +
             | 
| 173 | 
            +
              protected
         | 
| 174 | 
            +
             | 
| 175 | 
            +
              # @type [String]
         | 
| 176 | 
            +
              attr_writer :name
         | 
| 177 | 
            +
             | 
| 178 | 
            +
              # @see Concern::Setup#setup_defaults
         | 
| 179 | 
            +
              # @type [String]
         | 
| 180 | 
            +
              attr_writer :path
         | 
| 181 | 
            +
             | 
| 182 | 
            +
              # @see Concern::Setup#setup_defaults
         | 
| 183 | 
            +
              # @type [Boolean]
         | 
| 184 | 
            +
              attr_writer :verbose
         | 
| 185 | 
            +
             | 
| 186 | 
            +
              # @see Concern::Setup#setup_defaults
         | 
| 187 | 
            +
              # @type [String]
         | 
| 188 | 
            +
              attr_writer :version
         | 
| 189 | 
            +
             | 
| 190 | 
            +
              # @type [String|nil]
         | 
| 191 | 
            +
              attr_writer :tasks_ns
         | 
| 192 | 
            +
             | 
| 193 | 
            +
              # @see Concern::Setup#setup_defaults
         | 
| 194 | 
            +
              # @type [String]
         | 
| 195 | 
            +
              attr_writer :tasks_load
         | 
| 196 | 
            +
             | 
| 197 | 
            +
              # @see Concern::Setup#setup_defaults
         | 
| 198 | 
            +
              # @type [String]
         | 
| 199 | 
            +
              attr_writer :run_as
         | 
| 200 | 
            +
             | 
| 201 | 
            +
              # @see Concern::Setup#setup_defaults
         | 
| 202 | 
            +
              # @type [String]
         | 
| 203 | 
            +
              attr_writer :exec_command
         | 
| 204 | 
            +
             | 
| 205 | 
            +
              # @type [Hash]
         | 
| 206 | 
            +
              attr_writer :ssh
         | 
| 207 | 
            +
             | 
| 208 | 
            +
              # @see Concern::Setup#setup_defaults
         | 
| 209 | 
            +
              # @type [Hash]
         | 
| 210 | 
            +
              attr_writer :commands
         | 
| 211 | 
            +
             | 
| 212 | 
            +
              # @see Concern::Setup#setup_defaults
         | 
| 213 | 
            +
              # @type [String|Symbol]
         | 
| 214 | 
            +
              attr_writer :docker_bin
         | 
| 215 | 
            +
             | 
| 216 | 
            +
              # @return [Runner]
         | 
| 217 | 
            +
              attr_reader :runner
         | 
| 218 | 
            +
             | 
| 219 | 
            +
              # Load tasks
         | 
| 220 | 
            +
              def tasks_load!
         | 
| 221 | 
            +
                self.tap { Loader.new(self).call }
         | 
| 222 | 
            +
              end
         | 
| 223 | 
            +
            end
         | 
| @@ -0,0 +1,79 @@ | |
| 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 | 
            +
            # Describe a command
         | 
| 12 | 
            +
            #
         | 
| 13 | 
            +
            # Command is able to run itself.
         | 
| 14 | 
            +
            class Kamaze::DockerImage::Command
         | 
| 15 | 
            +
              autoload :Shellwords, 'shellwords'
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              # @return [Hash]
         | 
| 18 | 
            +
              attr_reader :config
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              # @param [Array<String>] command
         | 
| 21 | 
            +
              # @param [Hash] config
         | 
| 22 | 
            +
              # @param [String|nil] extra
         | 
| 23 | 
            +
              def initialize(command, config = {}, extra = nil)
         | 
| 24 | 
            +
                command.clone.to_a.tap do |c|
         | 
| 25 | 
            +
                  extras = Shellwords.split(extra.to_s).compact
         | 
| 26 | 
            +
                  @parts = c.push(*extras).freeze
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                config.clone.to_h.tap do |c|
         | 
| 30 | 
            +
                  @config = c.freeze
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              # @return [Array<String>]
         | 
| 35 | 
            +
              def to_a
         | 
| 36 | 
            +
                parts.clone
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              # @return [String]
         | 
| 40 | 
            +
              def to_s
         | 
| 41 | 
            +
                Shellwords.join(self.to_a)
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              def run(&block)
         | 
| 45 | 
            +
                sh(*self.to_a, &block)
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              alias call run
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              # @return [Boolean]
         | 
| 51 | 
            +
              def execute
         | 
| 52 | 
            +
                system(*self.to_a)
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              protected
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              # @return [Array<String>]
         | 
| 58 | 
            +
              attr_reader :parts
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              # Get utils.
         | 
| 61 | 
            +
              #
         | 
| 62 | 
            +
              # return [Class]
         | 
| 63 | 
            +
              def utils
         | 
| 64 | 
            +
                if Gem::Specification.find_all_by_name('rake')
         | 
| 65 | 
            +
                  require 'rake'
         | 
| 66 | 
            +
                  require 'rake/file_utils'
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                Class.new { include FileUtils }.new
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              # @see https://github.com/ruby/rake/blob/124a03bf4c0db41cd80a41394a9e7c6426e44784/lib/rake/file_utils.rb#L43
         | 
| 73 | 
            +
              def sh(*cmd, &block)
         | 
| 74 | 
            +
                options = cmd.last.is_a?(Hash) ? cmd.pop : {}
         | 
| 75 | 
            +
                options[:verbose] = config[:verbose] unless options.key?(:verbose)
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                utils.sh(*cmd.map(&:to_s).push(options), &block)
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 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 | 
            +
            # rubocop:disable Style/Documentation
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            module Kamaze::DockerImage::Concern
         | 
| 14 | 
            +
              {
         | 
| 15 | 
            +
                Containers: 'containers',
         | 
| 16 | 
            +
                Setup: 'setup',
         | 
| 17 | 
            +
                Executable: 'executable',
         | 
| 18 | 
            +
                ReadableAttrs: 'readable_attrs',
         | 
| 19 | 
            +
              }.each { |k, v| autoload(k, "#{__dir__}/concern/#{v}") }
         | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            # rubocop:enable Style/Documentation
         | 
| @@ -0,0 +1,75 @@ | |
| 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 | 
            +
            # Provide containers method.
         | 
| 12 | 
            +
            module Kamaze::DockerImage::Concern::Containers
         | 
| 13 | 
            +
              include Kamaze::DockerImage::Concern::Executable
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              autoload(:Open3, 'open3')
         | 
| 16 | 
            +
              autoload(:JSON, 'json')
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              protected
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              # List containers.
         | 
| 23 | 
            +
              #
         | 
| 24 | 
            +
              # Containers are indexed by name.
         | 
| 25 | 
            +
              #
         | 
| 26 | 
            +
              # @return [Hash{String => Hash}]
         | 
| 27 | 
            +
              def containers(all: true)
         | 
| 28 | 
            +
                [(config[:docker_bin] || executable).to_s].map(&:freeze).freeze.yield_self do |cmd|
         | 
| 29 | 
            +
                  cmd.dup.concat(['ps', (all ? '-a' : nil), '--format', '{{json .}}']).yield_self do |command|
         | 
| 30 | 
            +
                    [].tap do |items|
         | 
| 31 | 
            +
                      Open3.capture3(*command.compact).yield_self do |stdout, _, status|
         | 
| 32 | 
            +
                        stdout.lines.each { |line| items.push(JSON.parse(line)) } if status.success?
         | 
| 33 | 
            +
                      end
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                  end.map { |h| containers_maker.call(h) }.map { |h| [h.info['Name'].gsub(%r{^/*}, '').to_s, h] }.to_h
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              # Add some methods on retrieved info.
         | 
| 40 | 
            +
              #
         | 
| 41 | 
            +
              # @api private
         | 
| 42 | 
            +
              #
         | 
| 43 | 
            +
              # @return [Proc}
         | 
| 44 | 
            +
              def containers_maker
         | 
| 45 | 
            +
                # @type [Hash{String => Object}] given_data
         | 
| 46 | 
            +
                lambda do |given_data|
         | 
| 47 | 
            +
                  command = [(config[:docker_bin] || executable).to_s]
         | 
| 48 | 
            +
                            .map(&:freeze)
         | 
| 49 | 
            +
                            .concat(['inspect', '--format', '{{json .}}', given_data.fetch('ID')])
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  given_data.dup.tap do |result|
         | 
| 52 | 
            +
                    result.singleton_class.tap do |klass|
         | 
| 53 | 
            +
                      :inspection.tap do |method_name|
         | 
| 54 | 
            +
                        klass.__send__(:define_method, method_name) do
         | 
| 55 | 
            +
                          -> { Struct.new(:stdout, :stderr, :status).new(*Open3.capture3(*command.compact)) }
         | 
| 56 | 
            +
                        end
         | 
| 57 | 
            +
                        klass.__send__(:protected, method_name)
         | 
| 58 | 
            +
                      end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                      klass.__send__(:define_method, :info) do
         | 
| 61 | 
            +
                        inspection.call.yield_self do |v|
         | 
| 62 | 
            +
                          (v.status.success? ? JSON.parse(v.stdout) : nil).to_h
         | 
| 63 | 
            +
                        end
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                      klass.__send__(:define_method, :running?) do
         | 
| 67 | 
            +
                        self.info['State'].to_h['Status'] == 'running'
         | 
| 68 | 
            +
                      end
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
                  end.freeze
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
              # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
         | 
| 75 | 
            +
            end
         |