0
0

More than 5 years have passed since last update.

rsync する definitions

Last updated at Posted at 2015-02-06

chef 的には cookbook_file とかでなんとかするべき

definitions/rsync.rb
class ::Chef
  class Definition
    # rsync files from a host to localhost
    #
    # HOW TO USE:
    #
    # 1)
    #
    #    rsync "#{name}" do
    #      from "#{hostname}:#{from_path}"
    #      to   "#{to_path}"
    #    end
    #    
    #    rsync "#{name}" do
    #      from "#{from_path}"
    #      to   "#{hostname}:#{to_path}"
    #    end
    #
    # 2) notifies must specify `execute` not `rsync`
    #
    #    cookbook_file "/tmp/foo" do
    #      source "tmp/foo"
    #      notifies :run, "execute[#{name}]"
    #    end
    #    
    #    rsync "#{name}" do
    #      from "#{from_path}"
    #      to   "#{hostname}:#{to_path}"
    #    end
    #
    # OPTIONS:
    #
    # * command 
    #   * rsync command with option. Default: /usr/bin/rsync -avzl --exclude=.git --delete -e ssh'
    # * from:
    #   * rsync src.
    # * to:
    #   * rsync dest.
    #
    # Other options are same with `execute` resource.
    # See https://docs.chef.io/resource_execute.html
    #
    # NOTICE:
    #
    # Chef orginally does not support to deploy files from remote hosts via rsync. 
    # That said, rsync way should be removed sooner or later, and using only built-in resouces
    # such as `remote_file`, `cookbook_file`, `template`, `remote_directory`is better. 
    module Rsync
      # default command
      def default_command
        '/usr/bin/rsync -avzl --exclude=.git --delete -e ssh'
      end
      module_function :default_command

      # build rsync command
      #
      # @param [String] command Default is self.default_command
      # @param [String] from
      # @param [String] to
      def build_command(command: nil, from: , to: )
        command ||= self.default_command
        "#{command} #{from} #{to}"
      end
      module_function :build_command
    end
  end
end

opts = {
  :command => ::Chef::Definition::Rsync.default_command,
  :from    => nil,
  :to      => nil,
}

define :rsync, opts do
  raise ArgumentError, "`to` is missing for rsync" unless params[:to]
  name = params[:name]
  from = params[:from] || params[:name] # hostname:/path/to/file
  to   = params[:to]
  from = from.call if from.is_a?(Chef::DelayedEvaluator)
  to   = to.call   if to.is_a?(Chef::DelayedEvaluator)
  rsync = ::Chef::Definition::Rsync.build_command(
    command: params[:command],
    from: from,
    to: to,
  )
  execute_params = params.dup.tap do |params|
    params.delete(:name)
    params.delete(:command)
    params.delete(:from)
    params.delete(:to)
  end
  execute_params[:command] ||= rsync
  # ToDo: find better way to achieve idempotence
  execute_params[:only_if] ||= "test $(#{rsync} -n 2>&1 | wc -l) -gt 4" # assume -v is used
  execute name do
    execute_params.each {|key, val| send(key, *val) }
  end
end
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0