Module: Chef::Util::DSC::LocalConfigurationManager::Parser

Defined in:
lib/chef/util/dsc/lcm_output_parser.rb

Class Method Summary collapse

Class Method Details

.parse(lcm_output) ⇒ Object

Parses the output from LCM and returns a list of Chef::Util::DSC::ResourceInfo objects that describe how the resources affected the system

Example:

parse <<-EOF
What if: [Machine]: LCM: [Start Set      ]
What if: [Machine]: LCM: [Start Resource ] [[File]FileToNotBeThere]
What if: [Machine]: LCM: [Start Set      ] [[File]FileToNotBeThere]
What if:                                   [C:\ShouldNotExist.txt] removed
What if: [Machine]: LCM: [End Set        ] [[File]FileToNotBeThere] in 0.1 seconds
What if: [Machine]: LCM: [End Resource   ] [[File]FileToNotBeThere]
What if: [Machine]: LCM: [End Set        ]
EOF

would return

[
  Chef::Util::DSC::ResourceInfo.new(
    '[[File]FileToNotBeThere]',
    true,
    [
      '[[File]FileToNotBeThere]',
      '[C:\Shouldnotexist.txt]',
      '[[File]FileToNotBeThere] in 0.1 seconds'
    ]
  )
]


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
# File 'lib/chef/util/dsc/lcm_output_parser.rb', line 56

def self.parse(lcm_output)
  lcm_output ||= ""
  current_resource = Hash.new

  resources = []
  lcm_output.lines.each do |line|
    op_action, op_type, info = parse_line(line)

    case op_action
    when :start
      case op_type
      when :set
        if current_resource[:name]
          current_resource[:context] = :logging
          current_resource[:logs] = [info]
        end
      when :resource
        if current_resource[:name]
          resources.push(current_resource)
        end
        current_resource = { :name => info }
      else
        Chef::Log.debug("Ignoring op_action #{op_action}: Read line #{line}")
      end
    when :end
      # Make sure we log the last line
      if current_resource[:context] == :logging && info.include?(current_resource[:name])
        current_resource[:logs].push(info)
      end
      current_resource[:context] = nil
    when :skip
      current_resource[:skipped] = true
    when :info
      if current_resource[:context] == :logging
        current_resource[:logs].push(info)
      end
    end
  end

  if current_resource[:name]
    resources.push(current_resource)
  end

  if resources.length > 0
    build_resource_info(resources)
  else
    raise Chef::Exceptions::LCMParser, "Could not parse:\n#{lcm_output}"
  end
end