sous-chefs / homebrew

Development repository for the homebrew cookbook
https://supermarket.chef.io/cookbooks/homebrew
Apache License 2.0
152 stars 136 forks source link

get_version_from_formula: Couldn't find HOME environment #53

Closed ringods closed 9 years ago

ringods commented 10 years ago

I run Chef on Mac OS X via Launchd in interval mode instead of as a daemon. The homebrew::cask recipe is part of my run list, but I get the following error:

[2014-08-18T18:18:08+02:00] INFO: Processing package[brew-cask] action install (homebrew::cask line 22)
ESC[0m
================================================================================ESC[0m
ESC[31mError executing action `install` on resource 'package[brew-cask]'ESC[0m
================================================================================ESC[0m

ESC[0mArgumentErrorESC[0m
-------------ESC[0m
couldn't find HOME environment -- expanding `~'ESC[0m

ESC[0mCookbook Trace:ESC[0m
---------------ESC[0m
/var/chef/cache/cookbooks/homebrew/libraries/homebrew_package.rb:89:in `get_version_from_formula'
ESC[0m/var/chef/cache/cookbooks/homebrew/libraries/homebrew_package.rb:69:in `current_installed_version'
ESC[0m/var/chef/cache/cookbooks/homebrew/libraries/homebrew_package.rb:39:in `load_current_resource'ESC[0m

ESC[0mResource Declaration:ESC[0m
---------------------ESC[0m
# In /var/chef/cache/cookbooks/homebrew/recipes/cask.rb
ESC[0m
ESC[0m 22: package 'brew-cask'
ESC[0m
ESC[0mCompiled Resource:ESC[0m
------------------ESC[0m
# Declared in /var/chef/cache/cookbooks/homebrew/recipes/cask.rb:22:in `from_file'
ESC[0m
ESC[0mpackage("brew-cask") do
ESC[0m  action :install
ESC[0m  retries 0
ESC[0m  retry_delay 2
ESC[0m  guard_interpreter :default
ESC[0m  package_name "brew-cask"
ESC[0m  timeout 900
ESC[0m  cookbook_name "homebrew"
ESC[0m  recipe_name "cask"
ESC[0mend
ESC[0m
ESC[0m[2014-08-18T18:18:08+02:00] INFO: Running queued delayed notifications before re-raising exception
[2014-08-18T18:18:08+02:00] ERROR: Running exception handlers
[2014-08-18T18:18:08+02:00] ERROR: Exception handlers complete
[2014-08-18T18:18:08+02:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[2014-08-18T18:18:08+02:00] INFO: Sending resource update report (run-id: d837723e-bb95-4c9f-ba59-a77aa1a36a8a)
[2014-08-18T18:18:09+02:00] ERROR: package[brew-cask] (homebrew::cask line 22) had an error: ArgumentError: couldn't find HOME environment -- expanding `~'

In get_response_from_command, the HOME variable is explicitly retrieved. Shouldn't the same be done in get_response_from_formula ??

jtimberman commented 10 years ago

I'm not sure if adding HOME is going to work here. How are you running chef, is it something you could inject HOME into for launchd?

     setenv key value
              Set an environmental variable inside of launchd.

FWIW, In the PR for moving homebrew_package to Chef (v12), we remove the get_response_from_formula, and only use get_response_from_command. The reason is:

We implement a querying method that returns the JSON-as-Hash data for a formula per the Homebrew documentation. Previous implementations of this provider in the homebrew cookbook performed a bit of magic with the load path to get this information, but that is not any more robust than using the command-line interface that returns the same thing.

https://github.com/Homebrew/homebrew/wiki/Querying-Brew

ringods commented 10 years ago

@jtimberman I mentioned my setup in the beginning of my first comment: via LaunchD in interval mode instead of as a daemon.

The root cause is the same as for the initial ticket I filed on LaunchD support, way back mid-2012: https://tickets.opscode.com/browse/CHEF-3237

jtimberman commented 9 years ago

@ringods do you have a system you can try this on using chef 12 and the branch of this cookbook in PR #55?

ringods commented 9 years ago

@jtimberman, I have tested this. I updated my Berksfile with:

cookbook 'homebrew', '1.9.2',
    git: 'git@github.com:opscode-cookbooks/homebrew.git',
    branch: 'jtimberman/chef12-provider'

and .kitchen.yml with:

provisioner:
  require_chef_omnibus: 12.0.0

This is the output of my kitchen run:

-----> Installing Chef Omnibus (12.0.0)
       downloading https://www.getchef.com/chef/install.sh
         to file /tmp/install.sh
...
  * package[brew-cask] action install       [2014-12-07T03:05:25-08:00] INFO: Processing package[brew-cask] action install (homebrew::cask line 22)

- install version 0.49.0 of package brew-cask

So for the error at hand, it seems to pass, but just after it, I have an error with the package provider. My cookbook has this snippet:

# Add additional build-essential packages via Homebrew
%w(autoconf bison flex automake libtool pkg-config gcc46 libyaml readline libksba openssl).each do |pkg|
  package pkg do
    action :install
  end
end

The autoconf package installs fine, but the bison package installation fails:

  * package[bison] action install       [2014-12-07T03:05:38-08:00] INFO: Processing package[bison] action install (ad-buildtools::_cpp_mac_os_x line 24)
   ================================================================================
       Error executing action `install` on resource 'package[bison]'         ================================================================================

           NoMethodError
           -------------
           undefined method `[]' for nil:NilClass

Here is the stacktrace:

Generated at 2014-12-07 03:05:38 -0800
NoMethodError: package[bison] (ad-buildtools::_cpp_mac_os_x line 24) had an error: NoMethodError: undefined method `[]' for nil:NilClass
/opt/chef/embedded/apps/chef/lib/chef/provider/package/homebrew.rb:97:in `current_installed_version'
/opt/chef/embedded/apps/chef/lib/chef/provider/package/homebrew.rb:36:in `load_current_resource'
/opt/chef/embedded/apps/chef/lib/chef/provider.rb:128:in `run_action'
/opt/chef/embedded/apps/chef/lib/chef/resource.rb:654:in `run_action'
/opt/chef/embedded/apps/chef/lib/chef/runner.rb:49:in `run_action'
/opt/chef/embedded/apps/chef/lib/chef/runner.rb:81:in `block (2 levels) in converge'
/opt/chef/embedded/apps/chef/lib/chef/runner.rb:81:in `each'
/opt/chef/embedded/apps/chef/lib/chef/runner.rb:81:in `block in converge'
/opt/chef/embedded/apps/chef/lib/chef/resource_collection/resource_list.rb:83:in `block in execute_each_resource'
/opt/chef/embedded/apps/chef/lib/chef/resource_collection/stepable_iterator.rb:116:in `call'
/opt/chef/embedded/apps/chef/lib/chef/resource_collection/stepable_iterator.rb:116:in `call_iterator_block'
/opt/chef/embedded/apps/chef/lib/chef/resource_collection/stepable_iterator.rb:85:in `step'
/opt/chef/embedded/apps/chef/lib/chef/resource_collection/stepable_iterator.rb:104:in `iterate'
/opt/chef/embedded/apps/chef/lib/chef/resource_collection/stepable_iterator.rb:55:in `each_with_index'
/opt/chef/embedded/apps/chef/lib/chef/resource_collection/resource_list.rb:81:in `execute_each_resource'
/opt/chef/embedded/apps/chef/lib/chef/runner.rb:80:in `converge'
/opt/chef/embedded/apps/chef/lib/chef/client.rb:315:in `converge'
/opt/chef/embedded/apps/chef/lib/chef/client.rb:400:in `block in run'
/opt/chef/embedded/apps/chef/lib/chef/client.rb:399:in `catch'
/opt/chef/embedded/apps/chef/lib/chef/client.rb:399:in `run'
/opt/chef/embedded/apps/chef/lib/chef/application.rb:261:in `block in fork_chef_client'
/opt/chef/embedded/apps/chef/lib/chef/application.rb:249:in `fork'
/opt/chef/embedded/apps/chef/lib/chef/application.rb:249:in `fork_chef_client'
/opt/chef/embedded/apps/chef/lib/chef/application.rb:215:in `block in run_chef_client'
/opt/chef/embedded/apps/chef/lib/chef/local_mode.rb:38:in `with_server_connectivity'
/opt/chef/embedded/apps/chef/lib/chef/application.rb:201:in `run_chef_client'
/opt/chef/embedded/apps/chef/lib/chef/application/solo.rb:245:in `block in interval_run_chef_client'
/opt/chef/embedded/apps/chef/lib/chef/application/solo.rb:234:in `loop'
/opt/chef/embedded/apps/chef/lib/chef/application/solo.rb:234:in `interval_run_chef_client'
/opt/chef/embedded/apps/chef/lib/chef/application/solo.rb:224:in `run_application'
/opt/chef/embedded/apps/chef/lib/chef/application.rb:58:in `run'
/opt/chef/embedded/apps/chef/bin/chef-solo:25:in `<top (required)>'
/usr/bin/chef-solo:40:in `load'
/usr/bin/chef-solo:40:in `<main>'

Any idea?

jtimberman commented 9 years ago

Yeah, I reproduced this.

https://github.com/opscode/chef/blob/master/lib/chef/provider/package/homebrew.rb#L97

Here's the data from two different systems. One with bison installed:

{"name"=>"bison",
 "homepage"=>"http://www.gnu.org/software/bison/",
 "versions"=>{"stable"=>"3.0.2", "bottle"=>true, "devel"=>nil, "head"=>nil},
 "revision"=>0,
 "installed"=>
  [{"version"=>"3.0.2",
    "used_options"=>[],
    "built_as_bottle"=>nil,
    "poured_from_bottle"=>true}],
 "linked_keg"=>nil,
 "keg_only"=>true,
 "dependencies"=>[],
 "conflicts_with"=>[],
 "caveats"=>nil,
 "options"=>[]}

And one without it installed:

{"name"=>"bison",
 "homepage"=>"http://www.gnu.org/software/bison/",
 "versions"=>{"stable"=>"3.0.2", "bottle"=>true, "devel"=>nil, "head"=>nil},
 "revision"=>0,
 "installed"=>[],
 "linked_keg"=>nil,
 "keg_only"=>true,
 "dependencies"=>[],
 "conflicts_with"=>[],
 "caveats"=>nil,
 "options"=>[]}

When the package is not installed, the NoMethodError: undefined method '[]' for nil:NilClass exception is because brew_info['installed'] is an empty Array, and when we send #last to it, it returns nil

chef:recipe > brew_info['installed']
 => []
chef:recipe > brew_info['installed'].last
 => nil
chef:recipe > brew_info['installed'].last['version']
NoMethodError: undefined method `[]' for nil:NilClass
    from (irb#1):11

This needs to be fixed in Chef 12. I've opened this issue to address it.

jtimberman commented 9 years ago

This is fixed in Chef 12.0.2.