This file is indexed.

/usr/lib/ruby/vendor_ruby/cheffish/basic_chef_client.rb is in ruby-cheffish 4.0.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
require 'cheffish/version'
require 'chef/dsl/recipe'
require 'chef/event_dispatch/base'
require 'chef/event_dispatch/dispatcher'
require 'chef/node'
require 'chef/run_context'
require 'chef/runner'
require 'forwardable'
require 'chef/providers'
require 'chef/resources'

module Cheffish
  class BasicChefClient
    include Chef::DSL::Recipe

    def initialize(node = nil, events = nil, **chef_config)
      if !node
        node = Chef::Node.new
        node.name 'basic_chef_client'
        node.automatic[:platform] = 'basic_chef_client'
        node.automatic[:platform_version] = Cheffish::VERSION
      end

      # Decide on the config we want for this chef client
      @chef_config = chef_config

      with_chef_config do
        @cookbook_name = 'basic_chef_client'
        @event_catcher = BasicChefClientEvents.new
        dispatcher = Chef::EventDispatch::Dispatcher.new(@event_catcher)
        case events
        when nil
        when Array
          events.each { |e| dispatcher.register(e) } if events
        else
          dispatcher.register(events)
        end
        @run_context = Chef::RunContext.new(node, {}, dispatcher)
        @updated = []
        @cookbook_name = 'basic_chef_client'
      end
    end

    extend Forwardable

    # Stuff recipes need
    attr_reader :chef_config
    attr_reader :run_context
    attr_accessor :cookbook_name
    attr_accessor :recipe_name

    def add_resource(resource)
      with_chef_config do
        resource.run_context = run_context
        run_context.resource_collection.insert(resource)
      end
    end

    def load_block(&block)
      with_chef_config do
        @recipe_name = 'block'
        instance_eval(&block)
      end
    end

    def converge
      with_chef_config do
        Chef::Runner.new(run_context).converge
      end
    end

    def updates
      @event_catcher.updates
    end

    def updated?
      @event_catcher.updates.size > 0
    end

    # Builds a resource sans context, which can be later used in a new client's
    # add_resource() method.
    def self.build_resource(type, name, created_at=nil, &resource_attrs_block)
      created_at ||= caller[0]
      result = BasicChefClient.new.tap do |client|
        client.with_chef_config do
          client.build_resource(type, name, created_at, &resource_attrs_block)
        end
      end
      result
    end

    def self.inline_resource(provider, provider_action, *resources, &block)
      events = ProviderEventForwarder.new(provider, provider_action)
      client = BasicChefClient.new(provider.node, events)
      client.with_chef_config do
        resources.each do |resource|
          client.add_resource(resource)
        end
      end
      client.load_block(&block) if block
      client.converge
      client.updated?
    end

    def self.converge_block(node = nil, events = nil, &block)
      client = BasicChefClient.new(node, events)
      client.load_block(&block)
      client.converge
      client.updated?
    end

    def with_chef_config(&block)
      old_chef_config = Chef::Config.save
      if chef_config[:log_location]
        old_loggers = Chef::Log.loggers
        Chef::Log.init(chef_config[:log_location])
      end
      if chef_config[:log_level]
        old_level = Chef::Log.level
        Chef::Log.level(chef_config[:log_level])
      end
      # if chef_config[:stdout]
      #   old_stdout = $stdout
      #   $stdout = chef_config[:stdout]
      # end
      # if chef_config[:stderr]
      #   old_stderr = $stderr
      #   $stderr = chef_config[:stderr]
      # end
      begin
        deep_merge_config(chef_config, Chef::Config)
        block.call
      ensure
        # $stdout = old_stdout if chef_config[:stdout]
        # $stderr = old_stderr if chef_config[:stderr]
        if old_loggers
          Chef::Log.logger = old_loggers.shift
          old_loggers.each { |l| Chef::Log.loggers.push(l) }
        elsif chef_config[:log_level]
          Chef::Log.level = old_level
        end
        Chef::Config.restore(old_chef_config)
      end
    end

    def deep_merge_config(src, dest)
      src.each do |name, value|
        if value.is_a?(Hash) && dest[name].is_a?(Hash)
          deep_merge_config(value, dest[name])
        else
          dest[name] = value
        end
      end
    end

    class BasicChefClientEvents < Chef::EventDispatch::Base
      def initialize
        @updates = []
      end

      attr_reader :updates

      # Called after a resource has been completely converged.
      def resource_updated(resource, action)
        updates << [ resource, action ]
      end
    end

    class ProviderEventForwarder < Chef::EventDispatch::Base
      def initialize(provider, provider_action)
        @provider = provider
        @provider_action = provider_action
      end

      attr_reader :provider
      attr_reader :provider_action

      def resource_update_applied(resource, action, update)
        provider.run_context.events.resource_update_applied(provider.new_resource, provider_action, update)
      end
    end
  end
end