lib/kitchen/docker/helpers/cli_helper.rb in kitchen-docker-2.15.0 vs lib/kitchen/docker/helpers/cli_helper.rb in kitchen-docker-3.0.0
- old
+ new
@@ -1,172 +1,184 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-require 'kitchen'
-require 'kitchen/configurable'
-require 'kitchen/logging'
-require 'kitchen/shell_out'
-
-module Kitchen
- module Docker
- module Helpers
- module CliHelper
- include Configurable
- include Logging
- include ShellOut
-
- def docker_command(cmd, options={})
- docker = config[:binary].dup
- docker << " -H #{config[:socket]}" if config[:socket]
- docker << ' --tls' if config[:tls]
- docker << ' --tlsverify' if config[:tls_verify]
- docker << " --tlscacert=#{config[:tls_cacert]}" if config[:tls_cacert]
- docker << " --tlscert=#{config[:tls_cert]}" if config[:tls_cert]
- docker << " --tlskey=#{config[:tls_key]}" if config[:tls_key]
- logger.debug("docker_command: #{docker} #{cmd} shell_opts: #{docker_shell_opts(options)}")
- run_command("#{docker} #{cmd}", docker_shell_opts(options))
- end
-
- # Copied from kitchen because we need stderr
- def run_command(cmd, options = {})
- if options.fetch(:use_sudo, false)
- cmd = "#{options.fetch(:sudo_command, "sudo -E")} #{cmd}"
- end
- subject = "[#{options.fetch(:log_subject, "local")} command]"
-
- debug("#{subject} BEGIN (#{cmd})")
- sh = Mixlib::ShellOut.new(cmd, shell_opts(options))
- sh.run_command
- debug("#{subject} END #{Util.duration(sh.execution_time)}")
- sh.error!
- sh.stdout + sh.stderr
- rescue Mixlib::ShellOut::ShellCommandFailed => ex
- raise ShellCommandFailed, ex.message
- rescue Exception => error # rubocop:disable Lint/RescueException
- error.extend(Kitchen::Error)
- raise
- end
-
- def build_run_command(image_id, transport_port = nil)
- cmd = 'run -d'
- cmd << ' -i' if config[:interactive]
- cmd << ' -t' if config[:tty]
- cmd << build_env_variable_args(config[:env_variables]) if config[:env_variables]
- cmd << " -p #{transport_port}" unless transport_port.nil?
- Array(config[:forward]).each { |port| cmd << " -p #{port}" }
- Array(config[:dns]).each { |dns| cmd << " --dns #{dns}" }
- Array(config[:add_host]).each { |host, ip| cmd << " --add-host=#{host}:#{ip}" }
- Array(config[:volume]).each { |volume| cmd << " -v #{volume}" }
- Array(config[:volumes_from]).each { |container| cmd << " --volumes-from #{container}" }
- Array(config[:links]).each { |link| cmd << " --link #{link}" }
- Array(config[:devices]).each { |device| cmd << " --device #{device}" }
- Array(config[:mount]).each {|mount| cmd << " --mount #{mount}"}
- Array(config[:tmpfs]).each {|tmpfs| cmd << " --tmpfs #{tmpfs}"}
- cmd << " --name #{config[:instance_name]}" if config[:instance_name]
- cmd << ' -P' if config[:publish_all]
- cmd << " -h #{config[:hostname]}" if config[:hostname]
- cmd << " -m #{config[:memory]}" if config[:memory]
- cmd << " -c #{config[:cpu]}" if config[:cpu]
- cmd << " --gpus #{config[:gpus]}" if config[:gpus]
- cmd << " -e http_proxy=#{config[:http_proxy]}" if config[:http_proxy]
- cmd << " -e https_proxy=#{config[:https_proxy]}" if config[:https_proxy]
- cmd << ' --privileged' if config[:privileged]
- cmd << " --isolation #{config[:isolation]}" if config[:isolation]
- Array(config[:cap_add]).each { |cap| cmd << " --cap-add=#{cap}"} if config[:cap_add]
- Array(config[:cap_drop]).each { |cap| cmd << " --cap-drop=#{cap}"} if config[:cap_drop]
- Array(config[:security_opt]).each { |opt| cmd << " --security-opt=#{opt}"} if config[:security_opt]
- cmd << " --platform=#{config[:docker_platform]}" if config[:docker_platform]
- extra_run_options = config_to_options(config[:run_options])
- cmd << " #{extra_run_options}" unless extra_run_options.empty?
- cmd << " #{image_id} #{config[:run_command]}"
- logger.debug("build_run_command: #{cmd}")
- cmd
- end
-
- def build_exec_command(state, command)
- cmd = 'exec'
- cmd << ' -d' if config[:detach]
- cmd << build_env_variable_args(config[:env_variables]) if config[:env_variables]
- cmd << ' --privileged' if config[:privileged]
- cmd << ' -t' if config[:tty]
- cmd << ' -i' if config[:interactive]
- cmd << " -u #{config[:username]}" if config[:username]
- cmd << " -w #{config[:working_dir]}" if config[:working_dir]
- cmd << " #{state[:container_id]}"
- cmd << " #{command}"
- logger.debug("build_exec_command: #{cmd}")
- cmd
- end
-
- def build_copy_command(local_file, remote_file, opts = {})
- cmd = 'cp'
- cmd << ' -a' if opts[:archive]
- cmd << " #{local_file} #{remote_file}"
- cmd
- end
-
- def build_powershell_command(args)
- cmd = 'powershell -ExecutionPolicy Bypass -NoLogo '
- cmd << args
- logger.debug("build_powershell_command: #{cmd}")
- cmd
- end
-
- def build_env_variable_args(vars)
- raise ActionFailed, 'Environment variables are not of a Hash type' unless vars.is_a?(Hash)
-
- args = ''
- vars.each do |k, v|
- args << " -e #{k.to_s.strip}=\"#{v.to_s.strip}\""
- end
-
- args
- end
-
- def dev_null
- case RbConfig::CONFIG['host_os']
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
- 'NUL'
- else
- '/dev/null'
- end
- end
-
- def docker_shell_opts(options = {})
- options[:live_stream] = nil if options[:suppress_output]
- options.delete(:suppress_output)
-
- options
- end
-
- # Convert the config input for `:build_options` or `:run_options` in to a
- # command line string for use with Docker.
- #
- # @since 2.5.0
- # @param config [nil, String, Array, Hash] Config data to convert.
- # @return [String]
- def config_to_options(config)
- case config
- when nil
- ''
- when String
- config
- when Array
- config.map { |c| config_to_options(c) }.join(' ')
- when Hash
- config.map { |k, v| Array(v).map { |c| "--#{k}=#{Shellwords.escape(c)}" }.join(' ') }.join(' ')
- end
- end
- end
- end
- end
-end
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'kitchen'
+require 'kitchen/configurable'
+require 'kitchen/logging'
+require 'kitchen/shell_out'
+
+module Kitchen
+ module Docker
+ module Helpers
+ # rubocop:disable Metrics/ModuleLength, Style/Documentation
+ module CliHelper
+ include Configurable
+ include Logging
+ include ShellOut
+
+ # rubocop:disable Metrics/AbcSize
+ def docker_command(cmd, options={})
+ docker = config[:binary].dup
+ docker << " -H #{config[:socket]}" if config[:socket]
+ docker << ' --tls' if config[:tls]
+ docker << ' --tlsverify' if config[:tls_verify]
+ docker << " --tlscacert=#{config[:tls_cacert]}" if config[:tls_cacert]
+ docker << " --tlscert=#{config[:tls_cert]}" if config[:tls_cert]
+ docker << " --tlskey=#{config[:tls_key]}" if config[:tls_key]
+ logger.debug("docker_command: #{docker} #{cmd} shell_opts: #{docker_shell_opts(options)}")
+ run_command("#{docker} #{cmd}", docker_shell_opts(options))
+ end
+ # rubocop:enable Metrics/AbcSize
+
+ # Copied from kitchen because we need stderr
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
+ def run_command(cmd, options = {})
+ if options.fetch(:use_sudo, false)
+ cmd = "#{options.fetch(:sudo_command, "sudo -E")} #{cmd}"
+ end
+ subject = "[#{options.fetch(:log_subject, "local")} command]"
+
+ debug("#{subject} BEGIN (#{cmd})")
+ sh = Mixlib::ShellOut.new(cmd, shell_opts(options))
+ sh.run_command
+ debug("#{subject} END #{Util.duration(sh.execution_time)}")
+ sh.error!
+ sh.stdout + sh.stderr
+ rescue Mixlib::ShellOut::ShellCommandFailed => ex
+ raise ShellCommandFailed, ex.message
+ rescue Exception => error # rubocop:disable Lint/RescueException
+ error.extend(Kitchen::Error)
+ raise
+ end
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
+
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize
+ def build_run_command(image_id, transport_port = nil)
+ cmd = 'run -d'
+ cmd << ' -i' if config[:interactive]
+ cmd << ' -t' if config[:tty]
+ cmd << build_env_variable_args(config[:env_variables]) if config[:env_variables]
+ cmd << " -p #{transport_port}" unless transport_port.nil?
+ Array(config[:forward]).each { |port| cmd << " -p #{port}" }
+ Array(config[:dns]).each { |dns| cmd << " --dns #{dns}" }
+ Array(config[:add_host]).each { |host, ip| cmd << " --add-host=#{host}:#{ip}" }
+ Array(config[:volume]).each { |volume| cmd << " -v #{volume}" }
+ Array(config[:volumes_from]).each { |container| cmd << " --volumes-from #{container}" }
+ Array(config[:links]).each { |link| cmd << " --link #{link}" }
+ Array(config[:devices]).each { |device| cmd << " --device #{device}" }
+ Array(config[:mount]).each {|mount| cmd << " --mount #{mount}"}
+ Array(config[:tmpfs]).each {|tmpfs| cmd << " --tmpfs #{tmpfs}"}
+ cmd << " --name #{config[:instance_name]}" if config[:instance_name]
+ cmd << ' -P' if config[:publish_all]
+ cmd << " -h #{config[:hostname]}" if config[:hostname]
+ cmd << " -m #{config[:memory]}" if config[:memory]
+ cmd << " -c #{config[:cpu]}" if config[:cpu]
+ cmd << " --gpus #{config[:gpus]}" if config[:gpus]
+ cmd << " -e http_proxy=#{config[:http_proxy]}" if config[:http_proxy]
+ cmd << " -e https_proxy=#{config[:https_proxy]}" if config[:https_proxy]
+ cmd << ' --privileged' if config[:privileged]
+ cmd << " --isolation #{config[:isolation]}" if config[:isolation]
+ Array(config[:cap_add]).each { |cap| cmd << " --cap-add=#{cap}"} if config[:cap_add]
+ Array(config[:cap_drop]).each { |cap| cmd << " --cap-drop=#{cap}"} if config[:cap_drop]
+ Array(config[:security_opt]).each { |opt| cmd << " --security-opt=#{opt}"} if config[:security_opt]
+ cmd << " --platform=#{config[:docker_platform]}" if config[:docker_platform]
+ extra_run_options = config_to_options(config[:run_options])
+ cmd << " #{extra_run_options}" unless extra_run_options.empty?
+ cmd << " #{image_id} #{config[:run_command]}"
+ logger.debug("build_run_command: #{cmd}")
+ cmd
+ end
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize
+
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/AbcSize
+ def build_exec_command(state, command)
+ cmd = 'exec'
+ cmd << ' -d' if config[:detach]
+ cmd << build_env_variable_args(config[:env_variables]) if config[:env_variables]
+ cmd << ' --privileged' if config[:privileged]
+ cmd << ' -t' if config[:tty]
+ cmd << ' -i' if config[:interactive]
+ cmd << " -u #{config[:username]}" if config[:username]
+ cmd << " -w #{config[:working_dir]}" if config[:working_dir]
+ cmd << " #{state[:container_id]}"
+ cmd << " #{command}"
+ logger.debug("build_exec_command: #{cmd}")
+ cmd
+ end
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/AbcSize
+
+ def build_copy_command(local_file, remote_file, opts = {})
+ cmd = 'cp'
+ cmd << ' -a' if opts[:archive]
+ cmd << " #{local_file} #{remote_file}"
+ cmd
+ end
+
+ def build_powershell_command(args)
+ cmd = 'powershell -ExecutionPolicy Bypass -NoLogo '
+ cmd << args
+ logger.debug("build_powershell_command: #{cmd}")
+ cmd
+ end
+
+ def build_env_variable_args(vars)
+ raise ActionFailed, 'Environment variables are not of a Hash type' unless vars.is_a?(Hash)
+
+ args = ''
+ vars.each do |k, v|
+ args << " -e #{k.to_s.strip}=\"#{v.to_s.strip}\""
+ end
+
+ args
+ end
+
+ def dev_null
+ case RbConfig::CONFIG['host_os']
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
+ 'NUL'
+ else
+ '/dev/null'
+ end
+ end
+
+ def docker_shell_opts(options = {})
+ options[:live_stream] = nil if options[:suppress_output]
+ options.delete(:suppress_output)
+
+ options
+ end
+
+ # Convert the config input for `:build_options` or `:run_options` in to a
+ # command line string for use with Docker.
+ #
+ # @since 2.5.0
+ # @param config [nil, String, Array, Hash] Config data to convert.
+ # @return [String]
+ # rubocop:disable Metrics/CyclomaticComplexity
+ def config_to_options(config)
+ case config
+ when nil
+ ''
+ when String
+ config
+ when Array
+ config.map { |c| config_to_options(c) }.join(' ')
+ when Hash
+ config.map { |k, v| Array(v).map { |c| "--#{k}=#{Shellwords.escape(c)}" }.join(' ') }.join(' ')
+ end
+ end
+ # rubocop:enable Metrics/CyclomaticComplexity
+ end
+ # rubocop:enable Metrics/ModuleLength, Style/Documentation
+ end
+ end
+end