如何使用 Chef 在本地移动/复制文件
Posted
技术标签:
【中文标题】如何使用 Chef 在本地移动/复制文件【英文标题】:How to move/copy files locally with Chef 【发布时间】:2013-10-13 19:33:13 【问题描述】:我还没有遇到可以在本地复制/移动文件的 Chef 资源。比如我想下载jetty hightide并解压。完成后,将所有文件复制到特定文件夹中,如下所示:
# mv /var/tmp/jetty-hightide-7.4.5.v20110725/* /opt/jetty/
顺便说一句,jettyhightide 解压缩后会为您提供一个文件夹,其余文件位于该文件夹内。因此unzip jetty-hightide-7.4.5.v20110725.zip -d /opt/jetty/
没有用,因为它会创建一个目录/opt/jetty/jetty-hightide-7.4.5.v20110725/*
,而我真正想要的是/opt/jetty/*
。因此,我正在 Chef 中寻找本地复制/移动资源。
【问题讨论】:
您能帮我解决以下问题吗? ***.com/questions/39105976/mv-resource-in-chef/… 您说“复制所有文件”,但随后显示“mv”命令,该命令移动不个副本 【参考方案1】:我通过使用bash
资源使其工作,如下所示:
bash "install_jettyhightide" do
code <<-EOL
unzip /var/tmp/jetty-hightide-7.4.5.v20110725.zip -d /opt/jetty/
mv /opt/jetty/jetty-hightide-7.4.5.v20110725/* /opt/jetty/
cp /opt/jetty/bin/jetty.sh /etc/init.d/jetty
update-rc.d jetty defaults
EOL
end
但我真的希望有一种厨师的方式来做这件事。在本地复制/移动文件将是系统管理员需要做的最通用的任务。
【讨论】:
“厨师”的做事方式看起来更像@CAMOBAP 示例中的“每个目录”示例——为每个目录和每个文件生成一个资源。这实际上对性能来说很糟糕。您所做的实际上是正确的,并且是 bash 资源的用例。您可以添加not_if
或 creates
来检查是否正在创建 /etc/init.d/jetty/jetty.sh 以使其更具幂等性。
注意:chef-client 中现在有 archive_file 资源,它比大多数这些 roll-your-own-execute-resource 方法更好【参考方案2】:
您可以试试ark 食谱。这会为您提取文件,然后您会注意到 execute
资源。
【讨论】:
+1 我强烈推荐这本食谱。简化归档文件的处理。还支持源安装。 是的,我知道方舟。但仅将其用于复制/移动将是一种矫枉过正的做法。我的主要目的是复制/移动文件而不是安装它们 vi .tar/.zip 存档。我真的很想知道为什么 opscode 不考虑创建一种复制/移动文件的厨师方式。 是的,我有点同意。但是他们不能启动一个支持everything的产品。 Ark 也适用于简单的解包,即使没有 ./configure && make && make install dance。 现在在 chef-client 中内置了一个 archive_file 资源。【参考方案3】:如何复制单个文件
第一种方式
我使用file
语句复制文件(编译时检查)
file "/etc/init.d/someService" do
owner 'root'
group 'root'
mode 0755
content ::File.open("/home/someService").read
action :create
end
这里:
"/etc/init.d/someService"
- 目标文件,
"/home/someService"
- 源文件
您也可以将::File.open("/home/someService").read
包装在lazy
块中
...
lazy ::File.open("/home/someService").read
...
第二种方式
用户remote_file
语句(运行时检查)
remote_file "Copy service file" do
path "/etc/init.d/someService"
source "file:///home/someService"
owner 'root'
group 'root'
mode 0755
end
第三条路
你也可以使用 shell/batch
对于每个目录
Dir[ "/some/directory/resources/**/*" ].each do |curr_path|
file "/some/target/dir/#Pathname.new(curr_path).basename" do
owner 'root'
group 'root'
mode 0755
content lazy IO.read(curr_path, mode: 'rb').read
action :create
end if File.file?(curr_path)
directory "/some/target/dir/#File.dirname(curr_path)" do
path curr_path
owner 'root'
group 'root'
mode 0755
action :create
end if File.directory?(curr_path)
end
这只是想法,因为这个例子中的子路径没有被正确处理。
【讨论】:
很好的答案!我特别喜欢上面的“第一种方式”,因为如果不更改文件内容,它将不会更新文件。值得一提的是,如果源文件是由 Chef 管理的,那么 ::File.open 必须 包裹在一个惰性块中,否则 Chef 在编译时会找不到文件。 lazy 属性仅适用于 Chef >= 11.6, >= 10.28(我相信)。 需要指出的是,使用远程文件可以绕过 Chef 要求该文件在编译时存在的问题。 请补充说明remote_file
和file
的区别还在于file
是在编译时执行的,而remote_file
是在时执行的>运行时间。因此,当您需要在运行时处理文件时 - remote_file
是一个很好的解决方法。
请务必注意,对于二进制文件,您需要将其更改为IO.read(curr_path, mode: 'rb')
,否则可能会损坏目标文件。
remote_file 对我有用,因为它允许我自动跟踪文件增量。谢谢!【参考方案4】:
我知道这个问题已经得到解答和讨论,但这是我在创建文件时使用的方法。
-
首先将文件包含在说明书的文件/默认文件夹下
然后在您的食谱上使用
cookbook_file
资源
例如:
cookbook_file "/server/path/to/file.ext" do
source "filename.ext"
owner "root"
group "root"
mode 00600
action :create_if_missing
end
来自厨师文档:https://docs.chef.io/resources/cookbook_file/
cookbook_file 资源用于从 将食谱中 files/ 目录的子目录复制到指定的 位于运行 chef-client 或 chef-solo 的主机上的路径。
【讨论】:
这篇文章是关于将目标机器上已经存在的文件移动到目标机器上的另一个位置。 cookbook_file 无法做到这一点。 cookbook_file 用于将文件从说明书复制到目标机器,而不是目标机器的本地。 我在 Ansible 上使用copy
模块做了一些操作,谢谢。【参考方案5】:
在 CHEF 中本地复制文件
file "C:/Users/Administrator/chef/1.xml"
do ---> tar content lazy
IO.read("C:/Users/Administrator/chef-repo/cookbooks/2.xml")
-->src
action :create
end
【讨论】:
非工作代码,这个想法已经在上面的先前答案中)【参考方案6】:除了您已经完成并接受它的方式之外,如果您只想像最初要求的那样运行一个命令(复制或移动),而不是运行一个命令块,那么您可以使用 @987654321 @资源:
execute "copy_core" do
command "mv /var/tmp/jetty-hightide-7.4.5.v20110725 /opt/jetty"
user "root"
end
也许这会帮助其他人在未来看到这个。
【讨论】:
这里警告:如果没有添加保护,这将在每次厨师运行时一次又一次地运行 mv,如果目标中的文件已被修改,任何更改都将丢失。 @Tensibai,他只是问如何在 Chef 中执行“mv”命令。这完全取决于你把这个块放在哪里。您可以随时在块中添加not_if File.exist?("/opt/jetty")
,这样如果它已经被复制就不会重做。
警告是针对此问题/答案的未来读者。 (解决 XY 问题并不总是最好的办法)【参考方案7】:
我实际上会使用类似以下的内容(注意“binread”),因为这适用于文本文件和二进制文件。使用“读取”会在二进制文件中产生令人惊讶的结果,特别是如果您同时使用 unix 和 windows 系统。
file destination do
content IO.binread(source)
action :create
end
【讨论】:
这实际上非常重要,如果您使用默认读取方法,处理 Java Keystore 文件之类的文件将会中断。【参考方案8】:如果您的配方已经绑定到 Windows,您可以使用嵌入式 PowerShell 脚本,如下所示:
# Copy files from "C:/foo/lib" to "C:/foo"
powershell_script "copy_lib" do
code <<-EOH
$ErrorActionPreference = "Stop"
Get-ChildItem -Path "C:/foo/lib" -File | Foreach-Object
Copy-Item -Path $_.Fullname -Destination "C:/foo" -Force
EOH
end
# Delete "C:/foo/lib" folder
powershell_script "delete_lib" do
code <<-EOH
$ErrorActionPreference = "Stop"
Remove-Item -Path "C:/foo/lib" -Recurse
EOH
end
【讨论】:
以上是关于如何使用 Chef 在本地移动/复制文件的主要内容,如果未能解决你的问题,请参考以下文章