2

I have a bash script ( let's say main.sh ) which I need to integrate with chef. Currently we are using "expect" to pass the parameters to main.sh.

Now I need to make script in such a way that the parameters for main.sh will be passed using attribute file in chef.

I know that we can put our code in a bash resource but i am struggling to pass the parameters like passwords, user names, ports using chef attributes ??

Below is how the script looks like:

#!/usr/bin/expect
set filename [lindex $argv 0]
set f [open $filename]
set inputs [split [read $f] "\n"]

# Below parameters i need to pass using chef attributes instead of expect inputs
lassign $inputs ADMIN_PASSWORD CREATE_USER USER_EMAIL FIRST_NAME LAST_NAME INST_PATH

#read -e -p "Enter the installation folder path(/<install_dir>/): " FILEPATH3
#FILEPATH3=$(echo $FILEPATH3 | sed 's/ /\\ /')


spawn "$INST_PATH/main.sh"

expect "Enter system admin password:"

send "$ADMIN_PASSWORD\r"

expect "Create a new user y/n (y):"

send "$CREATE_USER\r"

.............
.............
serenesat
  • 1,286
  • 1
  • 13
  • 29
Krishna Sharma
  • 151
  • 1
  • 2
  • 6

3 Answers3

2

The Chef documentation on the bash resource has an example of passing attribute data to a script. You should be able to adapt it to your needs, something like this with your expect script:

bash 'call main.sh and respond with attribute values' do
  cwd ::File.dirname('/usr/local/bin')
  code <<-EOH
    #!/usr/bin/expect
    set filename [lindex $argv 0]
    set f [open $filename]
    set inputs [split [read $f] "\n"]

    # Below parameters i need to pass using chef attributes instead of expect inputs
    lassign $inputs ADMIN_PASSWORD CREATE_USER USER_EMAIL FIRST_NAME LAST_NAME INST_PATH

    #read -e -p "Enter the installation folder path(/<install_dir>/): " FILEPATH3
    #FILEPATH3=$(echo $FILEPATH3 | sed 's/ /\\ /')


    spawn "$INST_PATH/main.sh"

    expect "Enter system admin password:"

    send "#{node['admin_password']\r"

    expect "Create a new user y/n (y):"

    send "#{node['create_user']}\r"
  EOH
end

It would be better if main.sh accepted commandline arguments, as that would make your chef work much simpler, e.g.:

bash 'run main.sh' do
  cwd ::File.dirname('/usr/local/bin')
  code <<-EOH
    ./main.sh --admin_password #{node['admin_password']} --create_user #{node['create_user']}
    EOH
end

It would probably be even simpler, if main.sh was short, to convert the script itself to a bash resource in Chef, like these other examples above.

As you can see, Chef doesn't have any 'expect' functionality in the bash resource, so you're still stuck with the same expect script, unless you can switch to passing values as commandline arguments or embed your main script in a Chef resource (removing the interactive prompts when you do).

Finally, if you know enough Ruby to reproduce your main.sh, you could also do a lot of this natively and stop using bash resources completely.

Martin
  • 146
  • 2
  • For More info, this is how I have set my attribute file: default[:simple_cb][:User_email]= '[email protected]' default[:simple_cb][:First_name]= 'xyz' default[:simple_cb][:last_name]= 'abc' & This is how I am trying to write my code in my default.rb recipe CREATE_USER = "#{node[:simple_cb][:Create_user]}" USER_EMAIL = "#{node[:simple_cb][:User_email]}" FIRST_NAME = "#{node[:simple_cb][:First_name]}" bash "run main" do cwd ::/tmp code <<-EOH #Not Sure How to Put my above mentioned Code here EOH not_if { Need to figure out what to put here } end – Krishna Sharma Sep 22 '15 at 11:44
  • i am not able to put my comment in proper format... apologies.. first time using stackexchange – Krishna Sharma Sep 22 '15 at 11:47
  • I'm not sure what you're asking in your latest comment. Just replace any regular text with `#{}` in the bash resource, and you'll get that value in the bash script being run. Unless you want to avoid running the script for some conditions, just omit `not_if { }`. – Martin Sep 22 '15 at 14:09
  • Hi Martin.. it seems expect doesn't work if i directly put it... but i found that you can use `expect -C " -------xxx----- expect eof"` inside bash... can you please tell me how to use `spawn` with `expect -C` ?? With this i will pass my script name with spawn – Krishna Sharma Sep 25 '15 at 15:42
0

I don't understand why you would use "expect" ...

Why not pass the variables in as "switches" ?

 myscript.sh -f myfile -u username 

or load the variables before the script:

 FILE=myfile USER=username myscript.sh

I think that would be a more typical use for a shell script.

Don W
  • 1
  • it is a very big script where lot of input was required.... i needed to automate the input parameters for which expect was used. – Krishna Sharma Sep 27 '15 at 13:33
-1

It worked with:

/usr/bin/expect -c ' 
--code-- 
interact
' 
jasonwryan
  • 71,734
  • 34
  • 193
  • 226
Krishna Sharma
  • 151
  • 1
  • 2
  • 6