在 Chef 中读取文件并创建用户
Reading a file and creating a user in Chef
我有一个 IP 地址列表。在那些 IP 前面我有一个用户名。我想要做的是让 Chef 读取具有 IP 和用户名的文件,一旦遇到 IP,它应该创建一个具有该名称的用户。
但是当我这样做时,我得到了一个用户,但用户名是一个数字。
这是我的食谱
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each_with_index do |ip,user|
if ip = node[:ipaddress]
user ip[user] do
action :create
supports :manage_home => true
comment 'Test User'
home '/home/ip[user]'
shell '/bin/bash'
password 'password'
end
end
end
我的users.txt文件
231.27.59.232, test1
272.27.59.15, tes2
985.54.25.22, test3
现在当我运行食谱时,这就是我得到的
Recipe: repo_update::users
* cookbook_file[/tmp/users.txt] action create (up to date)
* user[1] action create
- create user 1
* user[7] action create
- create user 7
* user[2] action create
- create user 2
请告诉我这里有什么问题。
问题出在这一行:
user ip[user] do
您正在对 ip
字符串调用 []
方法。此外,您将在资源 user
和块变量之间发生名称冲突。最后,您为每个用户提供了“/home/ip[user]”的主页。您需要将字符串放在 "
中,并将变量包装在 #{
和 }
中试试这个:
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each do |line|
entries = line.split(',')
ip = entries[0].strip
username = entries[1].strip
if ip = node[:ipaddress]
user username do
action :create
supports :manage_home => true
comment 'Test User'
home "/home/#{username}"
shell '/bin/bash'
password 'password'
end
end
end
另外,从一个文件中读取所有这些是一件非常不费力的事情。使用存储在环境变量中的数据包或散列,这也使您根本不需要循环:
userhash = node['my_users'][node['ipadddress']]
user userhash['username']
action :create
supports :manage_home => true
comment 'test user'
home userhash['home'] || "/home/#{userhash['username']"
shell userhash['shell'] || '/bin/bash'
password userhash['password'] || 'password'
end
这里有很多问题...Tejay 的回答是可行的方法,我将尝试解释为什么您的代码不起作用以及如何修复它以便稍后使用: )
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each_with_index do |ip,user|
puts "values are #{ip} and #{user}"
end
end
给出:
values are 231.27.59.232, test1
and 0
values are 272.27.59.15, tes2
and 1
values are 985.54.25.22, test3
and 2
each_with_index
不会神奇地将您的行分成两部分,它只会将最后一个参数分配给迭代中的实际索引。
您的代码的固定版本为:
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each do |line| # just iterate and get line
ip,myuser=line.gsub("\n",'').split(',') # set ip and myuser variable with values comma separated, using myuser to avoid conflict with the resource name. Using gsub to remove traling carriage return in user name
if ip == node[:ipaddress] # test equality, a single = will assign ip a value and always be true.
user myuser do # create the user using the variable, no need to interpolate here
action :create
supports :manage_home => true
comment 'Test User'
home "/home/#{myuser}" # use interpolation here inside double quotes (won't work in single quotes)
shell '/bin/bash'
password 'password'
end
end
end
end
我有一个 IP 地址列表。在那些 IP 前面我有一个用户名。我想要做的是让 Chef 读取具有 IP 和用户名的文件,一旦遇到 IP,它应该创建一个具有该名称的用户。 但是当我这样做时,我得到了一个用户,但用户名是一个数字。
这是我的食谱
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each_with_index do |ip,user|
if ip = node[:ipaddress]
user ip[user] do
action :create
supports :manage_home => true
comment 'Test User'
home '/home/ip[user]'
shell '/bin/bash'
password 'password'
end
end
end
我的users.txt文件
231.27.59.232, test1
272.27.59.15, tes2
985.54.25.22, test3
现在当我运行食谱时,这就是我得到的
Recipe: repo_update::users
* cookbook_file[/tmp/users.txt] action create (up to date)
* user[1] action create
- create user 1
* user[7] action create
- create user 7
* user[2] action create
- create user 2
请告诉我这里有什么问题。
问题出在这一行:
user ip[user] do
您正在对 ip
字符串调用 []
方法。此外,您将在资源 user
和块变量之间发生名称冲突。最后,您为每个用户提供了“/home/ip[user]”的主页。您需要将字符串放在 "
中,并将变量包装在 #{
和 }
中试试这个:
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each do |line|
entries = line.split(',')
ip = entries[0].strip
username = entries[1].strip
if ip = node[:ipaddress]
user username do
action :create
supports :manage_home => true
comment 'Test User'
home "/home/#{username}"
shell '/bin/bash'
password 'password'
end
end
end
另外,从一个文件中读取所有这些是一件非常不费力的事情。使用存储在环境变量中的数据包或散列,这也使您根本不需要循环:
userhash = node['my_users'][node['ipadddress']]
user userhash['username']
action :create
supports :manage_home => true
comment 'test user'
home userhash['home'] || "/home/#{userhash['username']"
shell userhash['shell'] || '/bin/bash'
password userhash['password'] || 'password'
end
这里有很多问题...Tejay 的回答是可行的方法,我将尝试解释为什么您的代码不起作用以及如何修复它以便稍后使用: )
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each_with_index do |ip,user|
puts "values are #{ip} and #{user}"
end
end
给出:
values are 231.27.59.232, test1
and 0
values are 272.27.59.15, tes2
and 1
values are 985.54.25.22, test3
and 2
each_with_index
不会神奇地将您的行分成两部分,它只会将最后一个参数分配给迭代中的实际索引。
您的代码的固定版本为:
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each do |line| # just iterate and get line
ip,myuser=line.gsub("\n",'').split(',') # set ip and myuser variable with values comma separated, using myuser to avoid conflict with the resource name. Using gsub to remove traling carriage return in user name
if ip == node[:ipaddress] # test equality, a single = will assign ip a value and always be true.
user myuser do # create the user using the variable, no need to interpolate here
action :create
supports :manage_home => true
comment 'Test User'
home "/home/#{myuser}" # use interpolation here inside double quotes (won't work in single quotes)
shell '/bin/bash'
password 'password'
end
end
end
end