2013-04-04 3 views
6

저는 요리사를 매우 신으며 템플리트 작성을 시도하고 있습니다 (정말 멋지다). 이전 배포 구조에서는 단순히 복사하기를 원하는 디렉토리가있었습니다. 디렉토리의 파일 전체에 흩어져있는 여러 구성 매개 변수가있었습니다. 나는 앞서 가서 그 매개 변수를 애트리뷰트 파일 (훨씬 깨끗함)로 추상화하려고 시도했지만 Chef와 함께 설치하는 데 문제가 있습니다. 나는 ERB로 모든 파일의 확장자를 .erb로 끝내도록 수정했다. (필자는 레일스 배경에서 나온 것이므로 자연 스럽다.) 예를 들어 run.conf라는 파일이 있었는데 이제는 run.conf.erb라고합니다.반복적 인 디렉토리가있는 요리사 템플릿

이상적으로는 디렉토리의 모든 파일을 복사하고 (.erb 확장자를 제거한) .erb 파일을 제공하는 방법으로 하나의 템플릿 블록을 만들고 싶습니다. 여기에 지금까지 어디에 있어요의 예입니다 : 내가 템플릿/기본에서 서버라는 폴더를 뒀다

template "#{node["dcm4chee"]["home"]}" do 
    source "server/" 
    variables(
    "java_mem_opts" => node["dcm4chee"]["java_mem_opts"], 
    "db_username" => node["dcm4chee"]["admin"]["username"], 
    "db_password" => node["dcm4chee"]["admin"]["password"], 
    "db_hostname" => node["mysql"]["hostname"], 
    "db_port" => node["mysql"]["port"] 
) 
end 

은 해당 폴더 내가 템플릿 원하는 파일이 포함되어 있습니다. # {node [ "dcm4chee"] [ "home"]} 변수는 대상 컴퓨터에 파일을 저장하려는 위치입니다. 이상적으로는 배치를 위해 서버 디렉토리의 내용을 수정하면 제조법을 다룰 필요가 없기 때문에 제조법 내에서 특정 파일의 이름을 지정하지 않고이 작업을 수행하고 싶습니다.

이것이 가능합니까? 그렇다면 내가 뭘 잘못하고 있니? 그렇지 않다면, 내 대안은 무엇입니까.

감사

편집

이것에 대해 조금 생각 후, 나는이 일을 일부 사용자 지정 루비 코드를 사용했습니다. 다음은 Ruby_block 내의 초기 호출에서 tempate_dir을 참조하는 NoMethodError로 실패하는 현재 시도입니다.

def template_dir(file) 
    Dir.foreach("server") do |file| 
    if File.file?(file) 
     template "#{node["dcm4chee"]["home"]}/#{file}" do 
     source "server/#{file}" 
      variables(
      "java_mem_opts" => node["dcm4chee"]["java_mem_opts"], 
      "db_username" => node["dcm4chee"]["admin"]["username"], 
      "db_password" => node["dcm4chee"]["admin"]["password"], 
      "db_hostname" => node["mysql"]["hostname"], 
      "db_port" => node["mysql"]["port"] 
     ) 
     end 
    else 
     directory "#{node["dcm4chee"]["home"]}/#{file}" do 
     action :create 
     end 
     template_dir(file) 
    end 
    end 
end 

ruby_block "template the whole server directory" do 
    block do 
    template_dir("server") 
    end 
end 
+0

모든 파일에 매개 변수가있는 템플릿이 필요합니까 아니면 몇 개만 필요합니까? – cmur2

+0

지금 당장은 조금 있지만 이상적으로는 템플릿을 필요로하는 템플릿과 그렇지 않은 템플릿을 모두 함께 보관하고 싶습니다. 향후 파일을 추가/삭제하는 것이 쉽습니다. – Jon

+0

아마도 레시피에 비례하여 템플릿 디렉토리의 모든 파일을 가져 오기 위해 루비를 사용할 수 있습니다. 그런 다음'files.each' 블록 안에서'template' 리소스를 사용하기 만하면됩니다. – cassianoleal

답변

2

당신은 당신의 ruby_block의 내부 대신 잘 작동합니다 상단 레벨 -에 template_dir을 정의 할 수 있습니다.

find은 Ruby 표준 라이브러리의 일부이며, 재귀 적으로 디렉토리를 탐색합니다. 그것은 약간 청소기 뭔가 초래 사용 : 일반적으로

ruby_block "recursive templating" do 
    block do 
     require 'find' 
     root = 'server' 
     Find.find(root) do |file| 
      if File.file?(file) 
       template "#{node["dcm4chee"]["home"]}/#{file}" do 
        source file 
        variables(
         "java_mem_opts" => node["dcm4chee"]["java_mem_opts"], 
         "db_username" => node["dcm4chee"]["admin"]["username"], 
         "db_password" => node["dcm4chee"]["admin"]["password"], 
         "db_hostname" => node["mysql"]["hostname"], 
         "db_port" => node["mysql"]["port"] 
        ) 
       end 
      end 
     end 
    end 
end 

, 당신은 약간 복잡한 로직의 모든 종류를 작성하는 경우, 당신은 당신의 조리법으로 퍼팅 대신 LWRP를 작성하는 것이 좋습니다. 2 단계 컴파일/실행 문제는 블록이 template_dir을 찾을 수 없다는 것과 같은 많은 비 직관적 인 동작을 유발하고 LWRP를 작성하면 입력을 검증하고 테스트를 작성하며 멱등 원을 보장 할 수 있기 때문에 .

또한 '서버'문자열에 대해 다소 혼란 스럽습니다. 귀하의 templates 디렉토리로 해결할 환경이 확실하지 않습니다. 어떤 경우 든 요리 책에있는 모든 템플릿 목록에 액세스하려면 여기에서 사용할 수있는 배열이 있습니다. run_context.cookbook_collection[cookbook_name].template_filenames