Class: Backup::Actor

Inherits:
Object
  • Object
show all
Defined in:
lib/backup/actor.rb

Overview

An Actor is the entity that actually does the work of determining which servers should be the target of a particular task, and of executing the task on each of them in parallel. An Actor is never instantiated directly–rather, you create a new Configuration instance, and access the new actor via Configuration#actor.

Defined Under Namespace

Classes: Action

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Actor

:nodoc:



39
40
41
42
43
44
45
# File 'lib/backup/actor.rb', line 39

def initialize(config) #:nodoc:
  @configuration = config
  @action = {}
  @result_history = []
  @dirty_files = []
  @rotator = Backup::Rotator.new(self)
end

Instance Attribute Details

#actionObject (readonly)

A hash of the tasks known to this actor, keyed by name. The values are instances of Actor::Action.



19
20
21
# File 'lib/backup/actor.rb', line 19

def action
  @action
end

#configurationObject (readonly) Also known as: c

The configuration instance associated with this actor.



12
13
14
# File 'lib/backup/actor.rb', line 12

def configuration
  @configuration
end

#dirty_filesObject (readonly)

Returns an Array of Strings specifying dirty files. These files will be rm -rf when the cleanup task is called.



29
30
31
# File 'lib/backup/actor.rb', line 29

def dirty_files
  @dirty_files
end

#result_historyObject (readonly)

A stack of the results of the actions called



22
23
24
# File 'lib/backup/actor.rb', line 22

def result_history
  @result_history
end

#rotatorObject (readonly)

the rotator instance



25
26
27
# File 'lib/backup/actor.rb', line 25

def rotator
  @rotator
end

Instance Method Details

#cleanup(opts = {}) ⇒ Object

cleanup takes every element from @dirty_files and performs an rm -rf on the value



187
188
189
190
191
# File 'lib/backup/actor.rb', line 187

def cleanup(opts={})
  dirty_files.each do |f|
    rm_rf f
  end
end

#content(opts = {}) ⇒ Object

By default, :content can perform one of three actions

  • :is_file

  • :is_folder

+ :is_contents_of

Examples:

action :content, :is_file        => "/path/to/file"          # content is a single file
action :content, :is_folder      => "/path/to/folder"        # content is the folder itself
action :content, :is_contents_of => "/path/to/other/folder"  # files in folder/

:is_file and :is_folder are basically the same thing in that they backup the whole file/folder whereas :is_contents_of backs up the contents of the given folder.

Note that :is_contents_of performs a very spcific action:

  • a temporary directory is created

  • all of the files are moved (including subdirectories) into the temporary directory

  • the archive is created from the temporary directory

If you wish to copy the files out of the original directory instead of moving them. Then you may specify the copy option passing a true value like so:

action :content, :is_contents_of => "/path/to/other/folder",
                           :copy => true

This will copy recursively.

If this is not your desired behavior then you can easily write your own. Also, these options only work for local files. If you are getting the files from a foreign server you will have to write a custom :content method.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/backup/actor.rb', line 151

def content(opts={})
  return opts[:is_file]        if opts[:is_file] 
  return opts[:is_folder]      if opts[:is_folder]
  if opts[:is_contents_of]
    orig   = opts[:is_contents_of]
    tmpdir = c[:tmp_dir] + "/tmp_" + Time.now.strftime("%Y%m%d%H%M%S") +"_#{rand}"
    new_orig = tmpdir + "/" + File.basename(orig)
    mkdir_p tmpdir
    mkdir_p new_orig
    if opts[:copy]
      cp_r orig + '/.', new_orig
    else
      mv orig + '/.', new_orig
    end
    dirty_file new_orig
    return new_orig
  end
  if opts[:is_hg_repository]
    orig = opts[:is_hg_repository]
    name = opts[:as] || File.basename(orig)
    new_orig = c[:tmp_dir] + '/' + name
    sh "hg clone #{orig} #{new_orig}"
    dirty_file new_orig
    return new_orig
  end
  raise "Unknown option in :content. Try :is_file, :is_folder " +
        ":is_contents_of or :is_hg_repository"
end

#define_action(name, options = {}, &block) ⇒ Object

Define a new task for this actor. The block will be invoked when this task is called. todo, this might be more complex if the before and after tasks are going to be part of the input and output chain



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/backup/actor.rb', line 71

def define_action(name, options={}, &block)
  @action[name] = (options[:action_class] || Action).new(name, self, options)

  if self.respond_to?(name) && !( block_given? || options[:method] )
    # if it was already defined and we aren't trying to re-define it then
    # what we are trying to do is define it the same way it is defined now
    # only with options being sent to it. 
    metaclass.send(:alias_method, "old_#{name}".intern, name)
    #self.class.send(:alias_method, "old_#{name}".intern, name)
    #define_method("#{name.to_s}_new".intern) do
    define_method(name) do
      begin
       result =  self.send("old_#{name}", options)
      end
      result
    end
    return
  end

  define_method(name) do
    #logger.debug "executing task #{name}"
    begin
      if block_given?
        result = instance_eval( &block )
      elsif options[:method]
        #result = self.send(options[:method], options[:args])
        result = self.send(options[:method])
        # here we need to have a thing where we can send the arguments
        # define the method 'content' so that would take the other options
        # if there are options (any hash) just send along that hash. this needs more work
      end
    end
    result
  end

end

#dirty_file(string) ⇒ Object

Given name of a file in string adds that file to @dirty_files. These files will be removed when the cleanup task is called.



182
183
184
# File 'lib/backup/actor.rb', line 182

def dirty_file(string)
  @dirty_files << string
end

#metaclassObject



108
109
110
# File 'lib/backup/actor.rb', line 108

def metaclass
  class << self; self; end
end

#send_and_store(name) ⇒ Object



63
64
65
# File 'lib/backup/actor.rb', line 63

def send_and_store(name) 
    store_result self.send(name) if self.respond_to? name 
end

#start_process!Object

each action in the action_order is part of the chain. so you start by setting the output as ‘nil’ then you try to call before_ action, then store the output, then cal action with the args if action takes the args you are sending. if it doesnt give an intelligent error message. do this for all actions. then call after_action with the output if it exists. each time out are calilng the method with the arguemtns f the method exists and the method takes the arguments.



54
55
56
57
58
59
60
61
# File 'lib/backup/actor.rb', line 54

def start_process!
  configuration[:action_order].each do |a|
    self.send_and_store("before_" + a)
    self.send_and_store(a)
    self.send_and_store("after_"  + a)
  end
  last_result
end

#via_ftpObject



115
# File 'lib/backup/actor.rb', line 115

def via_ftp; rotator.rotate_via_ftp(last_result);  end

#via_mvObject

rotate Actions



113
# File 'lib/backup/actor.rb', line 113

def via_mv;  rotator.rotate_via_mv(last_result);   end

#via_s3Object



116
# File 'lib/backup/actor.rb', line 116

def via_s3;  rotator.rotate_via_s3(last_result);   end

#via_sshObject



114
# File 'lib/backup/actor.rb', line 114

def via_ssh; rotator.rotate_via_ssh(last_result);  end