18

I use Vagrant to spawn a standard "precise32" box and provision it with Chef so I can test my Node.js code on Linux when I work on a Windows machine. This works fine.

I also have this bash command so it auto installs my npm modules:

bash "install npm modules" do
  code <<-EOH
    su -l vagrant -c "cd /vagrant && npm install"
  EOH
end

This also works fine except that I never see the console output if it completes successfully. But I'd like to see it so we can visually monitor what is going on. This is not specific to npm.

I see this similar question with no concrete answers: Vagrant - how to print Chef's command output to stdout?

I tried specifying flags but I'm a terrible linux/ruby n00b and create either errors or no output at all, so please edit my snippet with an example of your solution.

Community
  • 1
  • 1
Bartvds
  • 3,340
  • 5
  • 30
  • 42

5 Answers5

16

I try to use logging when possible, but I've found that in some scenarios seeing the output is important. Here's the short version of the way I do it. Substituting the execute resource for the bash resource also works fine. Both standard error and standard output go into the file.

results = "/tmp/output.txt"
file results do
    action :delete
end

cmd = "ls  /"
bash cmd do
    code <<-EOH
    #{cmd} &> #{results}
    EOH
end

ruby_block "Results" do
    only_if { ::File.exists?(results) }
    block do
        print "\n"
        File.open(results).each do |line|
            print line
        end
    end
end
Tom Weiss
  • 797
  • 1
  • 8
  • 15
  • 3
    That works Tom. Instead of the loop you can also use print File.read(results). – max Dec 21 '13 at 09:21
  • 1
    Another option to use instead of the loop: `Chef::Log.info(IO.read(results))` – Joe Apr 27 '17 at 08:54
  • Good comment Joe, ruby is not my first, second, or third programming language so I don't know the shortcuts. – Tom Weiss Apr 27 '17 at 14:25
15

Use the live_stream attribute of the execute resource

execute 'foo' do
  command 'cat /etc/hosts'
  live_stream true
  action :run
end

Script output will be printed to the console

   Starting Chef Client, version 12.18.31
   resolving cookbooks for run list: ["apt::default", "foobar::default"]
   Synchronizing Cookbooks:
   Converging 2 resources
   Recipe: foobar::default
     * execute[foo] action run
       [execute] 127.0.0.1  default-ubuntu-1604 default-ubuntu-1604
          127.0.0.1 localhost
          127.0.1.1 vagrant.vm  vagrant
          ::1     localhost ip6-localhost ip6-loopback
          ff02::1 ip6-allnodes
          ff02::2 ip6-allrouters
       - execute cat /etc/hosts

https://docs.chef.io/resource_execute.html

spuder
  • 17,437
  • 19
  • 87
  • 153
  • 1
    I tried `live_stream true`. But this is not quite working for me. I have posted the details in https://stackoverflow.com/questions/51307728/chef-solo-getting-logs-from-a-bash-script. Any thoughts what could be going wrong? – tuk Jul 12 '18 at 15:30
  • 2
    Personally I think this is the best answer to this question. I am guessing it is not the top or accepted answer because `live_stream` wasn't supported when this question was asked or something along those lines. – jayhendren Oct 10 '18 at 20:01
9

When you run chef - suppose we are using chef-solo, you can use -l debug to output more debug information into stdout.

For example: chef-solo -c solo.rb -j node.json -l debug

For example, a simple cookbook as below:

$ tree 
.
├── cookbooks
│   └── main
│       └── recipes
│           └── default.rb
├── node.json
└── solo.rb

3 directories, 3 files

default.rb

bash "echo something" do
   code <<-EOF
     echo 'I am a chef!'
   EOF
end

You'll see the following output like below:

Compiling Cookbooks...
[2013-07-24T15:49:26+10:00] DEBUG: Cookbooks to compile: [:main]
[2013-07-24T15:49:26+10:00] DEBUG: Loading Recipe main via include_recipe
[2013-07-24T15:49:26+10:00] DEBUG: Found recipe default in cookbook main
[2013-07-24T15:49:26+10:00] DEBUG: Loading from cookbook_path: /data/DevOps/chef/cookbooks
Converging 1 resources
[2013-07-24T15:49:26+10:00] DEBUG: Converging node optiplex790
Recipe: main::default
  * bash[echo something] action run[2013-07-24T15:49:26+10:00] INFO: Processing bash[echo something] action run (main::default line 4)
[2013-07-24T15:49:26+10:00] DEBUG: Platform ubuntu version 13.04 found
I am a chef!
[2013-07-24T15:49:26+10:00] INFO: bash[echo something] ran successfully

    - execute "bash"  "/tmp/chef-script20130724-17175-tgkhkz"

[2013-07-24T15:49:26+10:00] INFO: Chef Run complete in 0.041678909 seconds
[2013-07-24T15:49:26+10:00] INFO: Running report handlers
[2013-07-24T15:49:26+10:00] INFO: Report handlers complete
Chef Client finished, 1 resources updated
[2013-07-24T15:49:26+10:00] DEBUG: Forked child successfully reaped (pid: 17175)
[2013-07-24T15:49:26+10:00] DEBUG: Exiting

I think it contains the information you want. For example, output and the exit status of the shell script/command.

BTW: looks like there is a limitation (prompt for password?), you won't be able to use su

[2013-07-24T15:46:10+10:00] INFO: Running queued delayed notifications before re-raising exception
[2013-07-24T15:46:10+10:00] DEBUG: Re-raising exception: Mixlib::ShellOut::ShellCommandFailed - bash[echo something] (main::default line 4) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '1'
---- Begin output of "bash"  "/tmp/chef-script20130724-16938-1jhil9v" ----
STDOUT: 
STDERR: su: must be run from a terminal
---- End output of "bash"  "/tmp/chef-script20130724-16938-1jhil9v" ----
Ran "bash"  "/tmp/chef-script20130724-16938-1jhil9v" returned 1
Terry Wang
  • 13,840
  • 3
  • 50
  • 43
3

I used the following:

bash "install npm modules" do
  code <<-EOH
    su -l vagrant -c "cd /vagrant && npm install"
  EOH
  flags "-x"
end

The flags property makes the command execute like bash -x script.sh

Shoan
  • 4,003
  • 1
  • 26
  • 29
0

Kind of related... setting the log_location (-L) to a file prevents the chef logs (Chef::Log.info() or simply log) from going to standard out.

You can override this to print the full log information to stdout

chef-client -L /dev/stdout
KCD
  • 9,873
  • 5
  • 66
  • 75