vgh 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +28 -0
- data/.rspec +2 -0
- data/.travis.yml +7 -0
- data/.yardopts +2 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.rdoc +121 -0
- data/Rakefile +25 -0
- data/bin/vgh +7 -0
- data/lib/vgh/apps/ec2_backup.rb +63 -0
- data/lib/vgh/apps.rb +22 -0
- data/lib/vgh/cli.rb +185 -0
- data/lib/vgh/configuration.rb +176 -0
- data/lib/vgh/extended_aws/extended_ec2/metadata.rb +46 -0
- data/lib/vgh/extended_aws/extended_ec2/snapshot.rb +90 -0
- data/lib/vgh/extended_aws/extended_ec2/volume.rb +66 -0
- data/lib/vgh/extended_aws/extended_ec2.rb +10 -0
- data/lib/vgh/extended_aws.rb +10 -0
- data/lib/vgh/logging.rb +66 -0
- data/lib/vgh/output.rb +113 -0
- data/lib/vgh/system/lvm.rb +81 -0
- data/lib/vgh/system/mysql.rb +56 -0
- data/lib/vgh/system.rb +21 -0
- data/lib/vgh/version.rb +9 -0
- data/lib/vgh.rb +60 -0
- data/spec/cli_spec.rb +25 -0
- data/spec/misc_spec.rb +25 -0
- data/spec/spec_helper.rb +7 -0
- data/tasks/documentation.rake +56 -0
- data/vgh.gemspec +27 -0
- metadata +185 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module VGH
|
6
|
+
module Extended_AWS
|
7
|
+
module Extended_EC2
|
8
|
+
|
9
|
+
# This class gathers metadata information about the current instance, used by
|
10
|
+
# the applications in this gem.
|
11
|
+
#
|
12
|
+
# == Usage
|
13
|
+
#
|
14
|
+
# data = Metadata.new
|
15
|
+
# id = data.instance_id
|
16
|
+
# root = data.root_device
|
17
|
+
#
|
18
|
+
class MetaData
|
19
|
+
|
20
|
+
# Query the API server for the instance ID
|
21
|
+
# @return [String, nil] The current instance's ID
|
22
|
+
def instance_id
|
23
|
+
begin
|
24
|
+
@instance_id = open('http://instance-data/latest/meta-data/instance-id').read
|
25
|
+
rescue
|
26
|
+
message.fatal 'Could not get Instance ID!'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Query the API server for the root device
|
31
|
+
# @return [String, nil] The root device of the current instance
|
32
|
+
def root_device
|
33
|
+
begin
|
34
|
+
@root_device = open('http://instance-data/latest/meta-data/block-device-mapping/root').read
|
35
|
+
rescue
|
36
|
+
message.fatal 'Could not get the root device!'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end # module Extended_EC2
|
43
|
+
end # module Extended_AWS
|
44
|
+
end # module VGH
|
45
|
+
|
46
|
+
require 'vgh/output'
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module VGH
|
2
|
+
module Extended_AWS
|
3
|
+
module Extended_EC2
|
4
|
+
|
5
|
+
# Creates a snapshot of the specified volume.
|
6
|
+
#
|
7
|
+
# == Usage
|
8
|
+
#
|
9
|
+
# snap = Snapshot.new.
|
10
|
+
# snap.create(id, tag)
|
11
|
+
#
|
12
|
+
class Snapshot
|
13
|
+
|
14
|
+
# Load all needed classes
|
15
|
+
def initialize
|
16
|
+
@instance_id = MetaData.new.instance_id
|
17
|
+
@fqdn = System.fqdn
|
18
|
+
end
|
19
|
+
|
20
|
+
# The workflow to create a snapshot:
|
21
|
+
# - create snapshot
|
22
|
+
# - add a name tag
|
23
|
+
# - add an info tag
|
24
|
+
# @param [String] volume_id The ID of the volume to snapshot
|
25
|
+
# @param [String] volume_tag The Tag of the volume to snapshot
|
26
|
+
def create(volume_id, volume_tag)
|
27
|
+
snapshot(volume_id, volume_tag)
|
28
|
+
name_tag
|
29
|
+
info_tag(volume_id)
|
30
|
+
message.info "Creating and tagging snapshot \"#{@snapshot.id}\""
|
31
|
+
end
|
32
|
+
|
33
|
+
# Creates a snapshot for the specified volume
|
34
|
+
# @param [String] volume_id The ID of the volume to snapshot
|
35
|
+
# @param [String] volume_tag The tag of the volume to snapshot
|
36
|
+
# @return [String, nil] The newly created snapshot object
|
37
|
+
def snapshot(volume_id, volume_tag)
|
38
|
+
@snapshot = ec2.volumes[volume_id].
|
39
|
+
create_snapshot("Backup for #{volume_id}(#{volume_tag})")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Creates a name tag for the newly created snapshot.
|
43
|
+
# The name is the FQDN of the current instance.
|
44
|
+
def name_tag
|
45
|
+
ec2.snapshots[@snapshot.id].tag('Name', :value => @fqdn)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Creates an info tag for the newly created snapshot
|
49
|
+
def info_tag(volume_id)
|
50
|
+
ec2.snapshots[@snapshot.id].tag("Backup_#{@instance_id}", :value => volume_id)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Purges expired snapshots
|
54
|
+
def purge
|
55
|
+
expired.each do |snapshot|
|
56
|
+
message.info "Deleting expired snapshot (#{snapshot.id})"
|
57
|
+
snapshot.delete
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Creates a list of expired snapshots according to the expiration time
|
62
|
+
# specified in the app's configuration file
|
63
|
+
# @return [Array] An array of expired snapshot objects
|
64
|
+
def expired
|
65
|
+
@expired = []
|
66
|
+
all.each {|snapshot|
|
67
|
+
if snapshot.start_time < (Time.now - $cfg[:expiration]*24*60*60)
|
68
|
+
@expired.push snapshot
|
69
|
+
end
|
70
|
+
}
|
71
|
+
return @expired
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns a list of snapshots that are named the same with the current FQDN.
|
75
|
+
def all
|
76
|
+
@all ||= ec2.snapshots.
|
77
|
+
with_owner('self').
|
78
|
+
tagged('Name').tagged_values(@fqdn)
|
79
|
+
end
|
80
|
+
|
81
|
+
end # class Snapshot
|
82
|
+
|
83
|
+
end # module Extended_EC2
|
84
|
+
end # module Extended_AWS
|
85
|
+
end # module VGH
|
86
|
+
|
87
|
+
require 'vgh/system'
|
88
|
+
require 'vgh/output'
|
89
|
+
require 'vgh/configuration'
|
90
|
+
require 'vgh/extended_aws/extended_ec2/metadata'
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module VGH
|
2
|
+
module Extended_AWS
|
3
|
+
module Extended_EC2
|
4
|
+
|
5
|
+
# Collects information about the EBS volumes attached to the current instance.
|
6
|
+
# == Usage
|
7
|
+
# @volume = Volume.new
|
8
|
+
# @volume.list.map {|id, info|
|
9
|
+
# puts id
|
10
|
+
# puts info[:tag]
|
11
|
+
# puts info[:device)
|
12
|
+
# }
|
13
|
+
#
|
14
|
+
class Volume
|
15
|
+
|
16
|
+
# Collects all needed variables
|
17
|
+
def initialize
|
18
|
+
@instance_id = MetaData.new.instance_id
|
19
|
+
end
|
20
|
+
|
21
|
+
# Creates a Hash collection of volumes containing their id, tag and device
|
22
|
+
# @return [Hash]
|
23
|
+
def list
|
24
|
+
@list = {}
|
25
|
+
mappings.map {|device, info|
|
26
|
+
volume_id = info.volume.id
|
27
|
+
@list[volume_id] = {
|
28
|
+
:device => device,
|
29
|
+
:tag => tag(volume_id)
|
30
|
+
}
|
31
|
+
}
|
32
|
+
return @list
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns a Hash containing the block device mappings of the current instance
|
36
|
+
# @return [Hash]
|
37
|
+
def mappings
|
38
|
+
message.info "Creating a list of volumes..."
|
39
|
+
@mappings ||= ec2.instances[@instance_id].block_device_mappings
|
40
|
+
end
|
41
|
+
|
42
|
+
# Get volume's Name tag
|
43
|
+
# @return [String] The tag of the volume or (NOTAG) if a tag does not exists.
|
44
|
+
def tag(volume_id)
|
45
|
+
v_tags = tags(volume_id)
|
46
|
+
v_tags.count == 0 ? @tag = '(NOTAG)' : @tag = v_tags.first.value
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns a collection of tags for the specified volume.
|
50
|
+
# @param [String] volume_id The id of the volume to query for tags.
|
51
|
+
def tags(volume_id)
|
52
|
+
@tags = ec2.tags.
|
53
|
+
filter('resource-type', 'volume').
|
54
|
+
filter('key', 'Name').
|
55
|
+
filter('resource-id', volume_id)
|
56
|
+
end
|
57
|
+
|
58
|
+
end # class Volume
|
59
|
+
|
60
|
+
end # module Extended_EC2
|
61
|
+
end # module Extended_AWS
|
62
|
+
end # module VGH
|
63
|
+
|
64
|
+
require 'vgh/output'
|
65
|
+
require 'vgh/configuration'
|
66
|
+
require 'vgh/extended_aws/extended_ec2/metadata'
|
data/lib/vgh/logging.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module VGH
|
4
|
+
|
5
|
+
# Returns log state
|
6
|
+
def log
|
7
|
+
if logging?
|
8
|
+
$log ||= Logging.new.log
|
9
|
+
else
|
10
|
+
$log ||= Logger.new('/dev/null')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# == Description:
|
15
|
+
#
|
16
|
+
# This class logs messages if logging is enabled from the command line
|
17
|
+
# options. The default location of the log files is +/var/log/vgh.log+.
|
18
|
+
#
|
19
|
+
# This class uses the Ruby Logger standard library.
|
20
|
+
#
|
21
|
+
#
|
22
|
+
# == Usage:
|
23
|
+
#
|
24
|
+
# log = Logging.new.log
|
25
|
+
# log.info "This is an info message"
|
26
|
+
#
|
27
|
+
class Logging
|
28
|
+
|
29
|
+
# Defaults
|
30
|
+
def defaults
|
31
|
+
@path = '/var/log/vgh.log'
|
32
|
+
@level = Logger::INFO
|
33
|
+
end
|
34
|
+
|
35
|
+
# Check log file existence
|
36
|
+
def initialize
|
37
|
+
defaults
|
38
|
+
validate_log_directory
|
39
|
+
end
|
40
|
+
|
41
|
+
# Creates a log directory and file if it does not already exist
|
42
|
+
def validate_log_directory
|
43
|
+
dir = File.dirname(@path)
|
44
|
+
Dir.mkdir(dir) unless File.exists?(dir)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Opens the log file
|
48
|
+
def log_file
|
49
|
+
File.open(@path, File::WRONLY | File::APPEND | File::CREAT)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Global, memoized, lazy initialized instance of a logger
|
53
|
+
def log
|
54
|
+
# Logger
|
55
|
+
@log ||= Logger.new(log_file)
|
56
|
+
@log.level = @level
|
57
|
+
@log.datetime_format = "%Y-%m-%d %H:%M " # simplify time output
|
58
|
+
@log
|
59
|
+
end
|
60
|
+
|
61
|
+
end # class Logging
|
62
|
+
|
63
|
+
end # module VGH
|
64
|
+
|
65
|
+
require 'vgh/cli'
|
66
|
+
|
data/lib/vgh/output.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
module VGH
|
2
|
+
|
3
|
+
# Creates a global message method
|
4
|
+
def message
|
5
|
+
$message ||= Output.new
|
6
|
+
end
|
7
|
+
|
8
|
+
# == Description:
|
9
|
+
#
|
10
|
+
# This class sends messages to +STDOUT+ or to a log file. It takes the following
|
11
|
+
# standard methods:
|
12
|
+
# - +debug+
|
13
|
+
# - +info+
|
14
|
+
# - +warn+
|
15
|
+
# - +error+
|
16
|
+
# - +fatal+
|
17
|
+
#
|
18
|
+
# If +stdout+ is called then the message is only sent to +STDOUT+.
|
19
|
+
#
|
20
|
+
# If +header+ or +footer+ is called then it displays them.
|
21
|
+
#
|
22
|
+
#
|
23
|
+
# == Usage:
|
24
|
+
# # Load output
|
25
|
+
# message = Output.new
|
26
|
+
#
|
27
|
+
# message.header
|
28
|
+
#
|
29
|
+
# message.info "Starting code"
|
30
|
+
# # Your code here
|
31
|
+
# message.info "End code"
|
32
|
+
#
|
33
|
+
# message.footer
|
34
|
+
#
|
35
|
+
class Output
|
36
|
+
|
37
|
+
# Debug message
|
38
|
+
attr_reader :debug
|
39
|
+
# Inforational message
|
40
|
+
attr_reader :info
|
41
|
+
# Warning message
|
42
|
+
attr_reader :warn
|
43
|
+
# Error message
|
44
|
+
attr_reader :error
|
45
|
+
# Fatal Error message
|
46
|
+
attr_reader :fatal
|
47
|
+
# Header
|
48
|
+
attr_reader :header
|
49
|
+
# Footer
|
50
|
+
attr_reader :footer
|
51
|
+
|
52
|
+
# Writes a debug log message and outputs to screen
|
53
|
+
def debug(message)
|
54
|
+
log.debug(message)
|
55
|
+
stdout message
|
56
|
+
end
|
57
|
+
|
58
|
+
# Writes an info log message and outputs to screen
|
59
|
+
def info(message)
|
60
|
+
log.info(message)
|
61
|
+
stdout message
|
62
|
+
end
|
63
|
+
|
64
|
+
# Writes an warn log message and outputs to screen
|
65
|
+
def warn(message)
|
66
|
+
log.warn(message)
|
67
|
+
stdout message
|
68
|
+
end
|
69
|
+
|
70
|
+
# Writes an error log message and outputs to screen
|
71
|
+
def error(message)
|
72
|
+
log.error(message)
|
73
|
+
stdout message
|
74
|
+
end
|
75
|
+
|
76
|
+
# Writes a fatal log message and outputs to screen
|
77
|
+
def fatal(message)
|
78
|
+
log.fatal(message)
|
79
|
+
stdout message
|
80
|
+
end
|
81
|
+
|
82
|
+
# Outputs a message to screen
|
83
|
+
def stdout(message)
|
84
|
+
puts message if verbose?
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns the header
|
88
|
+
def header
|
89
|
+
stdout <<END_HEADER
|
90
|
+
###############################################################################
|
91
|
+
VladGh.com - Scripts (v#{VERSION})
|
92
|
+
#{Time.now.strftime("%m/%d/%Y %H:%M:%S(%Z)")}
|
93
|
+
###############################################################################
|
94
|
+
|
95
|
+
END_HEADER
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns the footer
|
99
|
+
def footer
|
100
|
+
stdout <<END_FOOTER
|
101
|
+
|
102
|
+
###############################################################################
|
103
|
+
RUBY ROCKS!!!
|
104
|
+
###############################################################################"
|
105
|
+
END_FOOTER
|
106
|
+
end
|
107
|
+
|
108
|
+
end # class Output
|
109
|
+
end # module VGH
|
110
|
+
|
111
|
+
require 'vgh/cli'
|
112
|
+
require 'vgh/configuration'
|
113
|
+
require 'vgh/logging'
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module VGH
|
2
|
+
module System
|
3
|
+
|
4
|
+
# This class is able to suspend or resume logical volumes. The +lvm2+ package
|
5
|
+
# needs to be installed for this to work.
|
6
|
+
#
|
7
|
+
# Suspending a volume becomes useful if you want for example a consistent
|
8
|
+
# EC2 snapshot of it. Any I/O that has already been mapped by the device but
|
9
|
+
# has not yet completed will be flushed. Any further I/O to that device will
|
10
|
+
# be postponed for as long as the device is suspended.
|
11
|
+
#
|
12
|
+
#
|
13
|
+
# == Usage:
|
14
|
+
#
|
15
|
+
# lvm = System::LV.new
|
16
|
+
# lvm.suspend_lvs
|
17
|
+
# # run the code that takes the snapshot
|
18
|
+
# lvm.resume_lvs
|
19
|
+
#
|
20
|
+
class LV
|
21
|
+
|
22
|
+
# Loads variables and checks if LVM Tools are installed
|
23
|
+
def initialize
|
24
|
+
@dmcmd = '/sbin/dmsetup'
|
25
|
+
installed?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Warn message if LVM tools are not installed
|
29
|
+
def installed?
|
30
|
+
message.warn "LVM Tools are not installed" unless File.exists?(@dmcmd)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Test if logical volumes are present
|
34
|
+
# @return [Boolean]
|
35
|
+
def lvs_are_present?
|
36
|
+
lvs_are_present = false
|
37
|
+
@lvlist = `#{@dmcmd} ls | /bin/grep -E -v 'swap|root'`
|
38
|
+
if @lvlist != "No devices found\n" then
|
39
|
+
lvs_are_present = true
|
40
|
+
end
|
41
|
+
return lvs_are_present
|
42
|
+
end
|
43
|
+
|
44
|
+
# Suspend all logical volume
|
45
|
+
def suspend
|
46
|
+
if lvs_are_present?
|
47
|
+
suspend_lvs
|
48
|
+
else
|
49
|
+
message.info "No logical volumes found."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# The actual suspend action
|
54
|
+
def suspend_lvs
|
55
|
+
for lv_name in @lvlist.split[0]
|
56
|
+
message.info "Suspending Logical Volume '#{lv_name}'..."
|
57
|
+
`#{@dmcmd} suspend #{lv_name}`
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Resume all logical volumes
|
62
|
+
def resume
|
63
|
+
if lvs_are_present?
|
64
|
+
resume_lvs
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# The actual resume action
|
69
|
+
def resume_lvs
|
70
|
+
for lv_name in @lvlist.split[0]
|
71
|
+
message.info "Resuming Logical Volume '#{lv_name}'..."
|
72
|
+
`#{@dmcmd} resume #{lv_name}`
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end # class LV
|
77
|
+
end # module System
|
78
|
+
end # module VGH
|
79
|
+
|
80
|
+
require 'vgh/output'
|
81
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module VGH
|
2
|
+
module System
|
3
|
+
|
4
|
+
# This class checks if a local MySQL server is present and running.
|
5
|
+
# The credentials need to be specified in the app's configuration file.
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# == Usage
|
9
|
+
#
|
10
|
+
# mysql = MySQL.new
|
11
|
+
# mysql.flush
|
12
|
+
# # run backup
|
13
|
+
# mysql.unlock
|
14
|
+
#
|
15
|
+
class MySQL
|
16
|
+
|
17
|
+
# Load defaults
|
18
|
+
def initialize
|
19
|
+
@mysqladmin = '/usr/bin/mysqladmin'
|
20
|
+
@mysql = '/usr/bin/mysql'
|
21
|
+
@user = $cfg[:mysql_user]
|
22
|
+
@password = $cfg[:mysql_pwd]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check if server is running and we have access to the credentials file
|
26
|
+
# @return [Boolean]
|
27
|
+
def mysql_exists?
|
28
|
+
mysql_exists = false
|
29
|
+
if File.exists?(@mysqladmin)
|
30
|
+
mysql_exists = system "#{@mysqladmin} -s ping"
|
31
|
+
end
|
32
|
+
return mysql_exists
|
33
|
+
end
|
34
|
+
|
35
|
+
# Lock & Flush the MySQL tables
|
36
|
+
def flush
|
37
|
+
if mysql_exists?
|
38
|
+
message.info 'Locking MySQL tables...'
|
39
|
+
`#{@mysql} -u#{@user} -p#{@password} -e "FLUSH TABLES WITH READ LOCK"`
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Unlock the MySQL tables
|
44
|
+
def unlock
|
45
|
+
if mysql_exists?
|
46
|
+
message.info 'Unlocking MySQL tables...'
|
47
|
+
`#{@mysql} -u#{@user} -p#{@password} -e "UNLOCK TABLES"`
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end # class MySQL
|
52
|
+
end # module System
|
53
|
+
end # module VGH
|
54
|
+
|
55
|
+
require 'vgh/output'
|
56
|
+
require 'vgh/configuration'
|
data/lib/vgh/system.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module VGH
|
2
|
+
|
3
|
+
# This is a parent class for different system actions performed by the scripts
|
4
|
+
# included in this gem. For more information see the classes defined under
|
5
|
+
# this namespace.
|
6
|
+
#
|
7
|
+
# == Usage
|
8
|
+
#
|
9
|
+
# fqdn = System.fqdn
|
10
|
+
#
|
11
|
+
module System
|
12
|
+
|
13
|
+
# FQDN
|
14
|
+
# @return [String] The FQDN of the current machine.
|
15
|
+
def self.fqdn
|
16
|
+
$fqdn ||= `hostname -f`
|
17
|
+
end
|
18
|
+
|
19
|
+
end # module System
|
20
|
+
|
21
|
+
end # module VGH
|
data/lib/vgh/version.rb
ADDED
data/lib/vgh.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Try to load rubygems. Hey rubygems, I hate you.
|
2
|
+
begin
|
3
|
+
require 'rubygems'
|
4
|
+
rescue LoadError
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'aws-sdk'
|
8
|
+
require 'sinatra'
|
9
|
+
|
10
|
+
require 'yaml'
|
11
|
+
require 'logger'
|
12
|
+
require 'erb'
|
13
|
+
require 'open-uri'
|
14
|
+
require 'net/http'
|
15
|
+
require 'uri'
|
16
|
+
require 'optparse'
|
17
|
+
|
18
|
+
# See the {file:README.rdoc README} file.
|
19
|
+
module VGH
|
20
|
+
|
21
|
+
# The main run method
|
22
|
+
def run
|
23
|
+
|
24
|
+
# Check if this script is run with root credentials
|
25
|
+
root_check
|
26
|
+
|
27
|
+
# Display header
|
28
|
+
show_header
|
29
|
+
|
30
|
+
# Run apps
|
31
|
+
case app
|
32
|
+
when 'ec2-backup'
|
33
|
+
APPS::EC2_Backup.new.run
|
34
|
+
end
|
35
|
+
|
36
|
+
# Display footer
|
37
|
+
show_footer
|
38
|
+
|
39
|
+
end # end run method
|
40
|
+
|
41
|
+
# Returns the header
|
42
|
+
def show_header
|
43
|
+
message.header
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the footer
|
47
|
+
def show_footer
|
48
|
+
message.footer
|
49
|
+
end
|
50
|
+
|
51
|
+
# Raise error if this app is not run as root
|
52
|
+
def root_check
|
53
|
+
raise 'Must run as root' unless Process.uid == 0
|
54
|
+
end
|
55
|
+
|
56
|
+
end # module VGH
|
57
|
+
|
58
|
+
require "vgh/output"
|
59
|
+
require "vgh/apps"
|
60
|
+
require "vgh/apps/ec2_backup"
|
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'vgh'
|
3
|
+
require 'vgh/apps'
|
4
|
+
require 'vgh/cli'
|
5
|
+
|
6
|
+
describe "Command Line" do
|
7
|
+
VGH::APPS.list.map {|app_name|
|
8
|
+
it "Should accept '#{app_name}' as the first argument" do
|
9
|
+
ARGV[0] = app_name
|
10
|
+
VGH::CLI.new.options[:app].should eq app_name
|
11
|
+
end
|
12
|
+
}
|
13
|
+
|
14
|
+
it "Should enable verbosity" do
|
15
|
+
ARGV[0] = VGH::APPS.list.shuffle.first
|
16
|
+
ARGV.push('-v')
|
17
|
+
VGH::CLI.new.options[:verbose].should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "Should enable logging" do
|
21
|
+
ARGV[0] = VGH::APPS.list.shuffle.first
|
22
|
+
ARGV.push('-l')
|
23
|
+
VGH::CLI.new.options[:logging].should be_true
|
24
|
+
end
|
25
|
+
end
|
data/spec/misc_spec.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'vgh'
|
3
|
+
require 'vgh/cli'
|
4
|
+
require 'vgh/apps'
|
5
|
+
require 'vgh/output'
|
6
|
+
require 'vgh/logging'
|
7
|
+
require 'vgh/configuration'
|
8
|
+
|
9
|
+
describe "Various Tests" do
|
10
|
+
it "Should have an array of supported apps" do
|
11
|
+
VGH::APPS.list.should be_an Array
|
12
|
+
end
|
13
|
+
|
14
|
+
it "Should write logs" do
|
15
|
+
log = VGH::Logging.new.log
|
16
|
+
log.should_receive(:info).with("RSpec Test")
|
17
|
+
log.info("RSpec Test")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "Should write messages" do
|
21
|
+
message = VGH::Output.new
|
22
|
+
message.should_receive(:stdout).with("RSpec Test")
|
23
|
+
message.stdout("RSpec Test")
|
24
|
+
end
|
25
|
+
end
|