Class: Chef::Provider::Package::Dnf::PythonHelper

Inherits:
Object
  • Object
show all
Includes:
Mixin::ShellOut, Mixin::Which, Singleton
Defined in:
lib/chef/provider/package/dnf/python_helper.rb

Constant Summary collapse

DNF_HELPER =
::File.expand_path(::File.join(::File.dirname(__FILE__), "dnf_helper.py")).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#inpipeObject

Returns the value of attribute inpipe


36
37
38
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 36

def inpipe
  @inpipe
end

#outpipeObject

Returns the value of attribute outpipe


37
38
39
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 37

def outpipe
  @outpipe
end

#stderrObject

Returns the value of attribute stderr


35
36
37
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 35

def stderr
  @stderr
end

#stdinObject

Returns the value of attribute stdin


33
34
35
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 33

def stdin
  @stdin
end

#stdoutObject

Returns the value of attribute stdout


34
35
36
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 34

def stdout
  @stdout
end

#wait_thrObject

Returns the value of attribute wait_thr


38
39
40
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 38

def wait_thr
  @wait_thr
end

Instance Method Details

#checkObject


81
82
83
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 81

def check
  start if stdin.nil?
end

#compare_versions(version1, version2) ⇒ Object


85
86
87
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 85

def compare_versions(version1, version2)
  query("versioncompare", { "versions" => [version1, version2] }).to_i
end

#dnf_commandObject


42
43
44
45
46
47
48
49
50
51
52
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 42

def dnf_command
  # platform-python is used for system tools on RHEL 8 and is installed under /usr/libexec
  @dnf_command ||= begin
    cmd = which("platform-python", "python", "python3", "python2", "python2.7", extra_path: "/usr/libexec") do |f|
      shell_out("#{f} -c 'import dnf'").exitstatus == 0
    end
    raise Chef::Exceptions::Package, "cannot find dnf libraries, you may need to use yum_package" unless cmd

    "#{cmd} #{DNF_HELPER}"
  end
end

#options_params(options) ⇒ Object


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 89

def options_params(options)
  options.each_with_object({}) do |opt, h|
    if opt =~ /--enablerepo=(.+)/
      $1.split(",").each do |repo|
        h["repos"] ||= []
        h["repos"].push( { "enable" => repo } )
      end
    end
    if opt =~ /--disablerepo=(.+)/
      $1.split(",").each do |repo|
        h["repos"] ||= []
        h["repos"].push( { "disable" => repo } )
      end
    end
  end
end

#package_query(action, provides, version: nil, arch: nil, options: {}) ⇒ Object

NB: "options" here is the dnf_package options hash and is deliberately not **opts


108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 108

def package_query(action, provides, version: nil, arch: nil, options: {})
  parameters = { "provides" => provides, "version" => version, "arch" => arch }
  repo_opts = options_params(options || {})
  parameters.merge!(repo_opts)
  # XXX: for now we restart before and after every query with an enablerepo/disablerepo to clean the helpers internal state
  restart unless repo_opts.empty?
  query_output = query(action, parameters)
  version = parse_response(query_output.lines.last)
  Chef::Log.trace "parsed #{version} from python helper"
  restart unless repo_opts.empty?
  version
end

#reapObject


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 63

def reap
  unless wait_thr.nil?
    Process.kill("INT", wait_thr.pid) rescue nil
    begin
      Timeout.timeout(3) do
        wait_thr.value # this calls waitpid()
      end
    rescue Timeout::Error
      Process.kill("KILL", wait_thr.pid) rescue nil
    end
    stdin.close unless stdin.nil?
    stdout.close unless stdout.nil?
    stderr.close unless stderr.nil?
    inpipe.close unless inpipe.nil?
    outpipe.close unless outpipe.nil?
  end
end

#restartObject


121
122
123
124
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 121

def restart
  reap
  start
end

#startObject


54
55
56
57
58
59
60
61
# File 'lib/chef/provider/package/dnf/python_helper.rb', line 54

def start
  ENV["PYTHONUNBUFFERED"] = "1"
  @inpipe, inpipe_write = IO.pipe
  outpipe_read, @outpipe = IO.pipe
  @stdin, @stdout, @stderr, @wait_thr = Open3.popen3("#{dnf_command} #{outpipe_read.fileno} #{inpipe_write.fileno}", outpipe_read.fileno => outpipe_read, inpipe_write.fileno => inpipe_write, close_others: false)
  outpipe_read.close
  inpipe_write.close
end