Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Homebrew need sudoers right without password when using chef as service #105

Open
ygini opened this issue Aug 4, 2016 · 8 comments
Open

Comments

@ygini
Copy link

ygini commented Aug 4, 2016

Cookbook version

2.1.0

Chef-client version

12.12.15

Platform Details

OS X 10.11.6 with chef-client run as service (created by chef-client resource)

Scenario:

When deploying system, a kickstart script install chef and register workstation to my chef server and run content from a default role.

No one is connected and the workstation is made for multiple non admin user.

A default admin user is installed and set as target user for homebrew via node attributes.

Expected Result:

Homebrew should be able installed and scenario should continue.

Actual Result:

Homebrew install fail due to design errors in the way homebrew work (it's not your fault, homebrew is a PITA in term of system management, nothing is done properly).

Here is the error:

Expected process to exit with [0], but received '1'
---- Begin output of /var/chef/cache/homebrew_go ----
STDOUT: ==> This script will install:
/usr/local/bin/brew
/usr/local/Library/...
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
==> /usr/bin/sudo /bin/mkdir -p /Users/macadmin/Library/Caches/Homebrew
STDERR: sudo: no tty present and no askpass program specified
Failed during: /usr/bin/sudo /bin/mkdir -p /Users/macadmin/Library/Caches/Homebrew
---- End output of /var/chef/cache/homebrew_go ----
Ran /var/chef/cache/homebrew_go returned 1

Indeed, homebrew install script make a heavy use of sudo command. But they never thinked about mass deployment scenario where sudo isn't available…

To make this work you've to add a file with the following content to /etc/sudoers.d

<homebrew owner>        ALL=(ALL) NOPASSWD: ALL

And then, it work…

It might be interesting to package this hack into the homebrew installer recipe…

(of course, create this file only if needed and delete it as soon as possible)

@Sauraus
Copy link

Sauraus commented Oct 4, 2016

When you try to execute /var/chef/cache/homebrew_go you get this:

/var/chef/cache/homebrew_go
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
==> The following existing directories will be made group writable:
/usr/local/bin
==> The following existing directories will have their owner set to roblox:
/usr/local/bin
==> The following existing directories will have their group set to admin:
/usr/local/bin
==> The following new directories will be created:
/usr/local/Cellar
/usr/local/Homebrew
/usr/local/Frameworks
/usr/local/etc
/usr/local/include
/usr/local/lib
/usr/local/opt
/usr/local/sbin
/usr/local/share
/usr/local/share/zsh
/usr/local/share/zsh/site-functions
/usr/local/var

Press RETURN to continue or any other key to abort

When you press RETURN you get a prompt for the admin password.

Press RETURN to continue or any other key to abort
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/bin
Password:

@Sauraus
Copy link

Sauraus commented Oct 4, 2016

Actually you can make this much more restrictive by doing this

#{homebrew_owner} #{node['hostname']}=(root) NOPASSWD: /bin/chmod
#{homebrew_owner} #{node['hostname']}=(root) NOPASSWD: /usr/sbin/chown
#{homebrew_owner} #{node['hostname']}=(root) NOPASSWD: /bin/mkdir
#{homebrew_owner} #{node['hostname']}=(root) NOPASSWD: /usr/bin/chgrp
#{homebrew_owner} #{node['hostname']}=(root) NOPASSWD: /usr/bin/touch
#{homebrew_owner} #{node['hostname']}=(root) NOPASSWD: /usr/sbin/softwareupdate
#{homebrew_owner} #{node['hostname']}=(root) NOPASSWD: /bin/rm

that way at least you expose the bare minimum required permissions.

user = homebrew_owner
host = node['hostname']

@Sauraus
Copy link

Sauraus commented Oct 4, 2016

However this does not resolve the initial

Press RETURN to continue or any other key to abort

problem this is something entirely different.

Here is another thing I observed, when I run kitchen converge I do not get the prompt, however running the command on an physical node does create this prompt. The easiest workaround for the Press RETURN prompt is to add </dev/null to the execution which will suppress tty and thus the prompt.

@Sauraus
Copy link

Sauraus commented Oct 4, 2016

Here is the code in homebrew_go:

def wait_for_user
  puts
  puts "Press RETURN to continue or any other key to abort"
  c = getc
  # we test for \r and \n because some stuff does \r instead
  abort unless c == 13 or c == 10
end

Which is called right after listing all directories that will be created...

wait_for_user if STDIN.tty? && !ENV["TRAVIS"]

Sauraus added a commit to Sauraus/homebrew that referenced this issue Oct 5, 2016
@ygini
Copy link
Author

ygini commented Oct 5, 2016

Indeed, you can filter your sudo rights to be more restrictive, but that mean heavy testing on each new homebrew version to discover new wonderful idea they got…

Homebrew is poorly designed so trying to do things correctly when packaging homebrew might not be a really simple task.

For example, how does it play with last version of homebrew who finally do things correctly due to SIP restrictions in 10.12? (i.e.: don't put a mess in /usr/local but clean your room and stay in /usr/local/homebew)

@Sauraus
Copy link

Sauraus commented Oct 5, 2016

I actually tested this on 10.12 and 10.11 both behave in the same way and the brew install is still messed up. :(

I will however move the actual commands that we need sudo access to during the install into an attribute such that these can be fine tuned when brew install changes things.

@Sauraus
Copy link

Sauraus commented Oct 5, 2016

PR updated. :)

@kameghamegha
Copy link

Is there any other updates on this or the pull request? :) I'd really like to see this or another fix go in soon. This has been a big issue in our environment.

trinitronx added a commit to LyraPhase/lyraphase_workstation that referenced this issue Feb 5, 2017
trinitronx added a commit to LyraPhase/sprout-wrap that referenced this issue Feb 6, 2017
tuzz added a commit to tuzz/zz that referenced this issue Sep 10, 2017
In order to install homebrew, the script needs to
be run as the current user, but it also requires
sudo rights to change the ownership of
/usr/local/bin amongst other things.

Chef is being run in a subprocess and as a result,
there’s no TTY associated with the shell. This
means Homebrew can’t ask for a password when it
runs sudo and the process fails.

This workaround temporarily grants the user the
right to run sudo commands without a password for
the duration of the chef run. It revokes them at
the end, even if chef fails.

There’s some discussion about this here:
sous-chefs/homebrew#105
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants