1

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"

.............
.............
  • What should be the correct format of the template file? and the file name of the template? Thank you, – Vinay Anumalla Apr 22 '19 at 23:57
1

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.

|improve this answer|||||
  • For More info, this is how I have set my attribute file: default[:simple_cb][:User_email]= 'xyz@example.com' 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 #{<variable name>} 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.

|improve this answer|||||
  • 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
' 
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.