gat 0.2.8 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt CHANGED
@@ -1,3 +1,18 @@
1
+ == 0.2.11 2010-03-22
2
+ * Bugfix release
3
+ * Bug in reinterpreter_output_and_error was wrong and cutted up to last line whole ouput
4
+ * set_backups_to_delete crashed when no system backups must be deleted
5
+ * Fixed bug at program dependence. config['path'] return nil
6
+
7
+ == 0.2.10 2010-03-09
8
+ * Bugfix release
9
+ * Bug at dependence folder mount operation.
10
+
11
+ == 0.2.9 2010-03-05
12
+ * Improved DarBackup gatget
13
+ * Include SystemBackup to perform all related operations to search backups
14
+ * Removed Catalog from dar_backup operations. Running though dump backup content now. Less time, better performance
15
+
1
16
  == 0.2.8 2010-02-16
2
17
  * Bugfix release
3
18
  * ShellCommandChilds was only executing for the first child
data/PostInstall.txt CHANGED
@@ -1,22 +1,20 @@
1
- Gat Gem Post Install Doc
1
+ Gat Gem Post Install Doc
2
2
  ===============================================================================
3
3
 
4
- Gat provides several built in Gatgets. For now, it contains
4
+ Gat provides several built in Gatgets. For now, it contains
5
5
 
6
6
  - GatgetDarBackup => Performs and maintains a whole system of backups with
7
- dar (Disk Archiver for GNU/Linux)
7
+ dar (Disk Archiver for GNU/Linux)
8
8
 
9
9
 
10
- To use this, simply copy the file named launcher.rb to the gatget install
11
- folder (default by gem, /usr/lib/ruby/gems/ruby1.8/gat/gatgets/<gatget_name>)
12
- and place it under your local executable folder (for example: /usr/local/bin).
10
+ To use this, simply run $ gat command and follow instructions
13
11
 
14
12
 
15
- For more information on gat, see http://gat.rubyforge.org
13
+ For more information on gat, see http://gat.rubyforge.org
16
14
 
17
15
 
18
16
  ===============================================================================
19
- Copyright © 2007-2009 Gnoxys. http://www.gnoxys.net.
20
- Gat is released under GPL v3.0 or higther. See README for more information
17
+ Copyright © 2007-2009 Gnoxys. http://www.gnoxys.net.
18
+ Gat is released under GPL v3.0 or higther. See README for more information
21
19
 
22
20
 
data/Rakefile CHANGED
@@ -4,7 +4,9 @@ require 'rubygems'
4
4
  require 'hoe'
5
5
 
6
6
  Hoe.spec 'gat' do
7
- developer('gnoxys', 'soporte@gnoxys.net')
7
+ developer('gnoxys', 'soporte@gnoxys.net')
8
+ extra_deps << [ 'tmail', '>=1.2.3' ]
9
+ extra_deps << [ 'open4', '>=1.0' ]
8
10
 
9
11
  # self.rubyforge_name = 'blahx' # if different than 'blah'
10
12
  end
data/lib/gat.rb CHANGED
@@ -188,7 +188,7 @@ module Gat
188
188
  def get_flag(flag_name)
189
189
  ret = self.flags[flag_name]
190
190
  if ret == nil
191
- self.operation.gatget.logger.log("warning", "get_flag","Undefined flag #{flag_name}")
191
+ self.operation.gatget.logger.log("warning", "get_flag", "Undefined flag #{flag_name}")
192
192
  ret = false
193
193
  end
194
194
  ret
@@ -19,27 +19,28 @@ module Gat
19
19
 
20
20
  def run
21
21
  ret = nil
22
- # Shell Command can be multiple, that means the command will be execute over a foreach variable subtitutions.
23
- # That is usefull, for example, when you need to do the same actions with some variable subtition, like
24
- # a multiple files compression.
25
- @childs = (@config['multiple'] and @config['multiple'].any?) ? set_multiple_childs(@config['multiple']) : [ ]
26
-
27
- # If ShellCommand is multiple, then, we exec all of its childs
28
- # If not, we just execute ShellCommand instance
29
- if @childs.any?
30
- @childs.each { |child|
22
+ # Shell Command can be multiple, that means the command will be execute over a foreach variable subtitutions.
23
+ # That is usefull, for example, when you need to do the same actions with some variable subtition, like
24
+ # a multiple files compression.
25
+ @childs = (@config['multiple'] and @config['multiple'].any?) ? set_multiple_childs(@config['multiple']) : [ ]
26
+
27
+ # If ShellCommand is multiple, then, we exec all of its childs
28
+ # If not, we just execute ShellCommand instance
29
+ if @childs.any?
30
+ @childs.each { |child|
31
31
  if not child.exec
32
32
  ret = false
33
33
  end
34
34
  }
35
- else
36
- self.parsed_syntax = interpreter_parameters(self.syntax, self.operation.gatget)
37
- ret = exec(self.parsed_syntax)
38
- end
35
+ else
36
+ self.parsed_syntax = interpreter_parameters(self.syntax, self.operation.gatget)
39
37
 
40
- if self.config['output']
41
- self.operation.gatget.logger.log("direct", "action_output", self.output)
42
- end
38
+ ret = exec(self.parsed_syntax)
39
+ end
40
+
41
+ if self.config['output']
42
+ self.operation.gatget.logger.log("direct", "action_output", self.output)
43
+ end
43
44
  ret
44
45
  end
45
46
 
@@ -52,7 +53,7 @@ module Gat
52
53
  # Even it has some problems too. Open4 module has big problems when the stdout or the stderr comes
53
54
  # with tons of information. For example, with a mysqldump output.
54
55
  #
55
- # The solution presented here is a wapper through Process.fork. We create a new fork, making
56
+ # The solution presented here is a wrapper through Process.fork. We create a new fork, making
56
57
  # and the output is not managed by the ruby script itself but by the fork process.
57
58
  # IO.pipes are created to pass the stdout, stderr and stdin data through Gat proccess and Fork process
58
59
  #
data/lib/gat/boot.rb CHANGED
@@ -33,7 +33,7 @@ GAT_TEMPLATES = GAT_ROOT + '/templates'
33
33
  # External gems
34
34
  gems = [ 'ftools', 'rubygems', 'open4', 'yaml', 'erb', 'rdoc/usage', 'rdoc/code_objects',
35
35
  'rdoc/markup/simple_markup', 'rdoc/markup/simple_markup/to_flow', 'rdoc/ri/ri_formatter',
36
- 'rdoc/ri/ri_options', 'net/smtp', 'tmail', 'erb' ]
36
+ 'rdoc/ri/ri_options', 'net/smtp', 'tmail', 'erb', 'fileutils' ]
37
37
 
38
38
  # Gat Modules
39
39
  modules = [ 'debug', 'help', 'interpreter', 'extends', 'version', 'launcher', 'checks', 'email' ]
data/lib/gat/checks.rb CHANGED
@@ -103,8 +103,7 @@ module Gat
103
103
  r = FileUtils.mkdir(lockdir) rescue r = nil
104
104
  if not r.nil?
105
105
  # lock succeeded, install signal handlers and store the PID
106
- trap 0, proc { p "Trapped"
107
- FileUtils.rm_rf lockdir }
106
+ trap 0, proc { FileUtils.rm_rf lockdir }
108
107
  r = File.open(pidfile, 'w') {|f| f.write($$) }
109
108
  else
110
109
  # lock failed, now check if the other PID is alive
@@ -119,8 +118,7 @@ FileUtils.rm_rf lockdir }
119
118
  r = Process.kill(0, otherpid) rescue r = nil
120
119
  if r == nil
121
120
  # lock is stale, remove it and go on
122
- trap 0, proc { p "Trapped"
123
- FileUtils.rm_rf lockdir }
121
+ trap 0, proc { FileUtils.rm_rf lockdir }
124
122
  r = File.open(pidfile, 'w') {|f| f.write($$) } rescue r=nil
125
123
  return false
126
124
  else
@@ -0,0 +1,80 @@
1
+ =begin
2
+
3
+ :file => condition.rb
4
+ :author => (c) 2008-2009 A.C. Gnoxys info@gnoxys.net
5
+
6
+ ######################################################################################
7
+ ## This file is part of GAT: http://gat.rubyforge.org ##
8
+ ## ##
9
+ ## GAT (Gnoxys Administration Tools) is released under the GPL License 3 or higher. ##
10
+ ## You can get a copy of the license easily at http://www.gnu.org/licenses/gpl.html.##
11
+ ######################################################################################
12
+
13
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
14
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
17
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+
21
+ =end
22
+
23
+ module Gat
24
+
25
+ class Condition
26
+
27
+ include Gat::Checks
28
+ include Gat::Interpreter
29
+
30
+ attr_reader :operation
31
+ attr_reader :config
32
+ attr_reader :name
33
+ attr_reader :type
34
+ attr_reader :description
35
+
36
+ attr_reader :onfail
37
+ attr_reader :onfail_message
38
+
39
+ def initialize(name, config, operation)
40
+ operation.gatget.logger.log("trace", "condition", "Initialize condition #{ name }")
41
+ @operation = operation
42
+ @config = config
43
+ @name = name
44
+
45
+ @description = config['description'] || "Another Condition"
46
+
47
+ @type = config['type'] || 'check_true'
48
+ @onfail = config['onfail'] || 'abort'
49
+ @onfail_message = config['onfail_message'] || "Gatget Process fail at condition #{ self.name }"
50
+
51
+ end
52
+
53
+
54
+ def evalue
55
+ unless Gat::Checks.instance_methods.include?(self.type)
56
+ raise GatgetConfigException.new("Check condition method #{ self.type } not available at Gat::Checks", "evalue_condition")
57
+ end
58
+
59
+ condition_arguments = {}
60
+
61
+ self.config['arguments'].each_pair do |argument_name, argument_parameter|
62
+ condition_arguments[argument_name] = interpreter_parameter(argument_parameter, self.operation.gatget)
63
+ end
64
+
65
+ # Eval condition by send check_method
66
+ # if condition fail, onfail config will checked. unless it is different for 'abort' (default value)
67
+ # gat will stop the process thourgh GatgetProcessException
68
+ unless self.send(self.type, condition_arguments)
69
+ @@conditions_status = 'failed'
70
+ self.operation.gatget.logger.log('warning', 'condition_eval', "Condition #{ self.name } evalued at False")
71
+
72
+ if self.onfail == 'abort'
73
+ self.operation.gatget.logger.log('error', 'condition_eval', "Condition #{ self.name } abort Gatget")
74
+ self.operation.status = 'failed'
75
+ raise GatgetProcessException.new(self.onfail_message, "evalue_condition")
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -64,10 +64,8 @@ module Gat
64
64
  private
65
65
  # check if folder is mounted, if not, try it, if doesnt work, launch GatgetProcessException
66
66
  def mounted?
67
- unless already_mounted?
68
- unless mount_folder
69
- raise Gat::GatgetProcessException.new("Unable to mount folder #{ self.name } at #{ self.path }", "mounted")
70
- end
67
+ unless already_mounted? || mount_folder
68
+ raise Gat::GatgetProcessException.new("Unable to mount folder #{ self.name } at #{ self.path }", "mounted")
71
69
  end
72
70
  end
73
71
 
@@ -77,7 +75,7 @@ module Gat
77
75
  mounts_file = File.open('/proc/mounts', 'r')
78
76
  mounted = false
79
77
  mounts_file.each_line do |mount_line|
80
- mounted = true if mount_line.split(" ")[2].include?(self.path)
78
+ mounted = true if mount_line.split(" ")[1].include?(self.path)
81
79
  end
82
80
  mounted
83
81
  end
@@ -90,7 +88,7 @@ module Gat
90
88
 
91
89
  ignored, status_open4 = Process::waitpid2 pid_open4
92
90
 
93
- if status_open4.exitstatus == 0 # try to mount_folder
91
+ if status_open4.exitstatus == 0
94
92
  self.operation.gatget.logger.log("trace", "mount_folder", "Folder #{ self.name } nicely mounted ")
95
93
  ret = true
96
94
  else
@@ -11,7 +11,11 @@ module Gat
11
11
  end
12
12
 
13
13
  def evalue
14
- self.path || evalue_from_shell
14
+ evalue_from_path || evalue_from_shell
15
+ end
16
+
17
+ def evalue_from_path
18
+ self.value = self.path
15
19
  end
16
20
 
17
21
  # Program is evalued through 'which' shell command
@@ -33,4 +37,4 @@ module Gat
33
37
  end
34
38
  end
35
39
  end
36
- end
40
+ end
data/lib/gat/extends.rb CHANGED
@@ -46,21 +46,36 @@ end
46
46
  class File
47
47
  def self.nice_size(file)
48
48
  filesize = File.size(file)
49
-
50
- if filesize >= 1073741824
51
- filesize = "#{ filesize / 1073741824 } Gb."
52
- elsif filesize >= 1048576
53
- filesize = "#{ filesize / 1048576 } Mb."
54
- elsif filesize >= 1024
55
- filesize = "#{ filesize / 1024 } Kb."
56
- else
57
- filesize = "#{ filesize } bytes"
58
- end
59
-
60
- filesize
49
+ nice_file_size(filesize)
50
+ end
51
+ end
52
+
53
+ def nice_file_size(size)
54
+ if size >= 1073741824
55
+ filesize = "#{ (size.to_f / 1073741824.0).round_to(2) } Gb."
56
+ elsif size >= 1048576
57
+ filesize = "#{ (size.to_f / 1048576.0).round_to(2) } Mb."
58
+ elsif size >= 1024
59
+ filesize = "#{ (size.to_f / 1024.0).round_to(2) } Kb."
60
+ else
61
+ filesize = "#{ size } bytes"
61
62
  end
63
+ filesize
62
64
  end
63
65
 
66
+
67
+ # Float#round_to
68
+ # From: http://www.hans-eric.com/code-samples/ruby-floating-point-round-off/
69
+ # Source: --
70
+ # Just round a float number to x decimals
71
+ class Float
72
+ def round_to(x)
73
+ (self * 10**x).round.to_f / 10**x
74
+ end
75
+ end
76
+
77
+
78
+
64
79
  # Hash#deep_merge
65
80
  # From: http://pastie.textmate.org/pastes/30372, Elliott Hird
66
81
  # Source: http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
data/lib/gat/logger.rb CHANGED
@@ -141,12 +141,12 @@ module Gat
141
141
  @gatget.logger.log("direct", "operation_output_template", template.result(binding))
142
142
  end
143
143
 
144
- # Standar email output
144
+ # Standard email output
145
145
  # See output for more information
146
146
  def output_email
147
147
  # default email config is used
148
148
  unless @gatget.config['email_config']
149
- raise GatgetConfigException.new("Default email config is empty at @gatget.config['email_config']", "run_output_email")
149
+ raise GatgetConfigException.new("Default email config is empty at @gatget.config['email_config']", "logger:output_email")
150
150
  end
151
151
 
152
152
  if @gatget.operation.status == 'ok'
@@ -0,0 +1,195 @@
1
+
2
+ ###### Global variables, only accessible in yaml scripts via eval code
3
+
4
+ #### Identification, used in logs
5
+
6
+ subsystem_name: backup
7
+ subsystem_description: Irgat backup module
8
+ server_name: balrog
9
+ server_domain: gnoxys.net
10
+
11
+
12
+ ###### Logs definitions
13
+
14
+ script_log:
15
+
16
+ # Log to stdout, not the same as the debug output
17
+ stdout:
18
+ enable: false
19
+ level: 4 # 0.-No output, 1.-Errors, 2.-Warnings, 3.-Messages, 4.-Trace
20
+
21
+ # email log
22
+ mail:
23
+ enable: false
24
+ send_to: santi@gnoxys.net
25
+ smtp_mode: smtp # smtp or sendmail
26
+ level: 4 # see above
27
+ smtp_values: # smtp configuration
28
+ server: mail.gnoxys.net
29
+ port: 25
30
+ domain: gnoxys.net
31
+ user: santi@gnoxys.net
32
+ password:
33
+
34
+
35
+
36
+ ###### Script variables, used only in the yaml script
37
+ script_variables:
38
+
39
+ # User who should run the .rb script
40
+ run_as_user: gnoxys
41
+
42
+ # Path to the backups
43
+ working_path: /tmp/backups
44
+
45
+ # Array of folders to create inside working_path to store things that will be backed up
46
+ folders_tree:
47
+ - data
48
+ - data/local
49
+ - data/local/current # stores the '.dar' files
50
+ - data/local/old
51
+ - extras
52
+ - extras/mysql # stores the mysql dumps
53
+
54
+ # days in which a complete backup will be made (0 -> Sunday, 1 -> Monday, etc.)
55
+ # Put it into quotes!
56
+ complet_backup_days: "2"
57
+
58
+ # maximum complete backups to be stored in the system
59
+ max_stored_backups: 2
60
+
61
+ # Exclude folders from backup, absolute path without first slash
62
+ # for example var/tmp
63
+ # IMPORTANT: data and restore irgat::backup folders are by definition excluded.
64
+ # You don't need to write it here.
65
+ exclude_folders:
66
+ - boot
67
+ - dev
68
+ - var/tmp
69
+
70
+ # files ommited inside backup files, can contain wildcards
71
+ exclude_files:
72
+ - *.dar
73
+
74
+ # exclude types in the compress phase
75
+ exclude_to_compress:
76
+ - .gz
77
+ - .bz2
78
+ - .zip
79
+ - .png
80
+
81
+ # MySQL dump options
82
+ mysql_user:
83
+ mysql_pass:
84
+
85
+ # dar options
86
+ dar:
87
+ compression: 256 # enable compression. nil disable
88
+ file_size: 500M # size of division each file
89
+ enable_empty_folders: true # enable backup empty folders
90
+ root_backup: '/' # root folder from backup
91
+ encrypt_passwd: # password to encrypt backups
92
+ decrypt_passwd: # password to decrypt backups
93
+
94
+
95
+ ###### Script action definition
96
+ ###### Script actions consist of conditions and actions
97
+
98
+ sample_script_action:
99
+
100
+ # Script actions can be disabled. They are enabled by default
101
+ enabled: false
102
+ disabled: true # both of them work
103
+
104
+ # Conditions are checked before any subaction.
105
+ conditions: # Must be an array, hence the following hyphen
106
+ - sample_condition:
107
+
108
+ # Conditions can be disabled. They are enabled by default
109
+ enabled: false
110
+ disabled: true # both of them work
111
+
112
+ type: # Type of value to be checked:
113
+ # fixed: A literal value
114
+ # array: A literal array
115
+ # script_variable: one of the ones defined in the script_variables section
116
+ # script_array: one of the ones defined in the script_variables section
117
+ # eval: Ruby code to be evaluated
118
+ # dependence:
119
+ # folder/_a_folder
120
+ # programs/_a_program
121
+ value: # definition of the value to be checked
122
+
123
+ negated: false # conditions can be negated, defaults to false
124
+
125
+ onfail: fail # What to do if condition fails:
126
+ # skip .- skips this subaction
127
+ # continue .- skips this condition
128
+ # fail .- exits script
129
+ post_eval: code # code to be evaluated after getting the value (%).
130
+ # Example: if % print true else print false end
131
+
132
+ arguments: # conditions can have arguments
133
+ - sample_argument:
134
+ type: # same as condition
135
+ value: # same as condition
136
+
137
+
138
+ # Actions included in script actions are executed if all the conditions are met
139
+ actions:
140
+ # Actions can be disabled. They are enabled by default
141
+ enabled: false
142
+ disabled: true # both of them work
143
+
144
+ - sample_action: # Must be an array, hence the following hyphen
145
+ # Actions can be 'command' or 'set_variable'
146
+ - set_variable:
147
+ name: # Script variable name
148
+ type: # same as condition above
149
+ value: # same as condition above
150
+
151
+ - command:
152
+ type: shell | ruby | shell.foreach | ruby.foreach
153
+
154
+ syntax: # syntax of the command.
155
+ # % is a placeholder for arguments: cd %
156
+
157
+ arguments: # same as conditions
158
+
159
+ onfail: # same values as conditions
160
+
161
+ # For types shell.foreach and ruby.foreach:
162
+ source_action: # Name of the action that produced the array to be processed.
163
+ # Each element of the array is named 'line'
164
+
165
+
166
+ ###### Optional initialize script
167
+
168
+ initialize:
169
+ conditions:
170
+ - condition_1:
171
+ - condition_2:
172
+
173
+ actions:
174
+ - action_1:
175
+ - action_2:
176
+
177
+
178
+ ###### The actions of the script, not including the optional initalize action
179
+
180
+ script_actions:
181
+ - script_action_1:
182
+ - script_action_2:
183
+
184
+
185
+
186
+ ###### Known issues
187
+ #
188
+ # There are a number of problems with writing ruby expressions in yaml code
189
+ # 1.- String concatenation:
190
+ #
191
+ # 2.- Don't use return statements in eval code:
192
+ # return statements, besides returning a value, will end the calling irgat script function
193
+
194
+
195
+