Chef食谱是否遵循固定步骤?现有食谱代码存疑求解答
Do Chef Recipes Follow Fixed Execution Steps?
Absolutely! Chef recipes follow a predictable two-phase execution flow that’s critical to wrap your head around when writing them:
- Compile Phase: Chef first reads all your recipe code, parses resources to build a "resource collection" (a list of all desired system changes), and runs any raw Ruby code that isn’t wrapped in a resource. This happens before any actual modifications are made to the system.
- Converge Phase: Chef works through the resource collection in order, executing each resource to make sure the system matches the desired state you’ve defined.
Feedback on Your Current Code
Looking at your snippet, there’s a key timing issue that’s probably causing problems. Let’s break it down:
- The
directoryresource: This is scheduled to run during the converge phase, meaning/opt/test/scriptswon’t exist until Chef starts making changes to the system. - The raw Ruby download code: This runs during the compile phase—before the directory is created. So when
File.write('/opt/test/scripts/pair.sh', response.body)tries to save the file, it’ll throw an error because the parent folder doesn’t exist yet. - The
not_ifcondition: Your current checkgrep /opt/testdoesn’t actually verify if the directory exists. It’s searching for the string "/opt/test" in standard input, which isn’t what you want. You should use a command that directly checks for the directory, liketest -d /opt/test/scripts.
Improved Version Using Chef Resources
Instead of raw Ruby, use Chef’s built-in resources which are designed to work seamlessly with the two-phase flow. Here’s a better approach:
# Create the directory first (runs in converge phase) directory '/opt/test/scripts' do owner 'root' group 'root' mode '0755' action :create recursive true not_if 'test -d /opt/test/scripts' end # Download the file using Chef's remote_file resource (runs after directory is created) remote_file '/opt/test/scripts/pair.sh' do source 'https://repo.test2.io/BwIaTHE0ohsUts74LYZMzrt/pair.sh' owner 'root' group 'root' mode '0755' action :create end
This setup ensures:
- The
directoryresource guarantees the folder exists before the file is downloaded. remote_filehandles downloading, file creation, and permissions all in one idempotent resource (it won’t re-download or reconfigure the file if it already matches the desired state).- The
not_ifcondition correctly checks for the directory’s existence.
Content of the question originates from Stack Exchange, question author: anish anil
相关产品推荐
相关产品推荐

