shnell 0.1.0 → 0.2.0
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/bin/shnell +97 -20
- data/lib/backup.rb +149 -0
- data/lib/shnell.rb +1 -1
- metadata +7 -9
- data/.gitignore +0 -21
- data/Rakefile +0 -33
- data/shnell.gemspec +0 -52
data/bin/shnell
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'commander/import'
|
5
|
-
require
|
5
|
+
require 'filander'
|
6
|
+
require File.join(File.dirname(__FILE__), '../lib/shnell')
|
6
7
|
|
7
8
|
program :name, 'shnell'
|
8
9
|
program :version, Shnell::VERSION
|
@@ -11,24 +12,66 @@ program :help, 'Author', 'Johannes Jörg Schmidt, TF <schmidt@netzmerk.com>'
|
|
11
12
|
|
12
13
|
default_command :help
|
13
14
|
|
14
|
-
SCRIPTS_ROOT
|
15
|
+
SCRIPTS_ROOT = Pathname.new(Dir.pwd)
|
16
|
+
CONFIG_FILENAME = File.join(SCRIPTS_ROOT, "config.yml")
|
17
|
+
|
18
|
+
def scripts(pattern = nil)
|
19
|
+
if pattern
|
20
|
+
exp = "**/*#{pattern}*.rb"
|
21
|
+
else
|
22
|
+
exp = '**/*.rb'
|
23
|
+
end
|
24
|
+
Dir[SCRIPTS_ROOT.join(exp)].select { |f| File.basename(f) != 'backup.rb' }.sort
|
25
|
+
end
|
26
|
+
|
27
|
+
def backup_scripts(pattern = nil)
|
28
|
+
if pattern
|
29
|
+
exp = "**/*#{pattern}*/backup.rb"
|
30
|
+
else
|
31
|
+
exp = '**/backup.rb'
|
32
|
+
end
|
33
|
+
Dir[SCRIPTS_ROOT.join(exp)].sort
|
34
|
+
end
|
35
|
+
|
36
|
+
def say_script(filename, message, quiet = false)
|
37
|
+
return if quiet
|
38
|
+
name = Pathname.new(filename).relative_path_from(SCRIPTS_ROOT)
|
39
|
+
message = "#{message} #{name.sub(/\.rb$/, '')}..."
|
40
|
+
message = $terminal.color(message, :bold) if defined? $terminal
|
41
|
+
say message
|
42
|
+
end
|
15
43
|
|
16
44
|
command :list do |c|
|
17
|
-
c.syntax = 'shnell list [pattern]'
|
18
|
-
c.description = 'List available scripts.'
|
45
|
+
c.syntax = 'shnell list [scrips|backups] [pattern]'
|
46
|
+
c.description = 'List available scripts and backups.'
|
47
|
+
|
48
|
+
c.example "List all available scripts and backups", "shnell list"
|
49
|
+
c.example "List all available backups", "shnell list backups"
|
50
|
+
c.example "List all available scripts", "shnell list scripts"
|
51
|
+
c.example 'List available scripts which include "ruby"', "shnell list scripts ruby"
|
19
52
|
|
20
53
|
c.action do |args, options|
|
54
|
+
name = args.shift
|
21
55
|
pattern = args.shift
|
22
|
-
|
23
|
-
|
24
|
-
|
56
|
+
if name == "scripts"
|
57
|
+
scripts(pattern).each do |f|
|
58
|
+
path = Pathname.new(f)
|
59
|
+
name = path.relative_path_from(SCRIPTS_ROOT)
|
60
|
+
puts name.sub(/\.rb$/, '')
|
61
|
+
end
|
62
|
+
elsif name == "backups"
|
63
|
+
backup_scripts(pattern).each do |f|
|
64
|
+
path = Pathname.new(f)
|
65
|
+
name = path.relative_path_from(SCRIPTS_ROOT)
|
66
|
+
puts name.sub(/\.rb$/, '')
|
67
|
+
end
|
25
68
|
else
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
69
|
+
all = scripts(pattern) + backup_scripts(pattern)
|
70
|
+
all.sort.each do |f|
|
71
|
+
path = Pathname.new(f)
|
72
|
+
name = path.relative_path_from(SCRIPTS_ROOT)
|
73
|
+
puts name.sub(/\.rb$/, '')
|
74
|
+
end
|
32
75
|
end
|
33
76
|
end
|
34
77
|
end
|
@@ -42,12 +85,17 @@ command :run do |c|
|
|
42
85
|
c.option '-q', '--quiet', 'Supress status output'
|
43
86
|
c.option '-s', '--skip', 'Skip files that already exist'
|
44
87
|
|
88
|
+
c.example 'Run script "./basic/apache.rb"', "shnell run basic/apache"
|
89
|
+
c.example "Run all available scripts", "shnell run all"
|
90
|
+
c.example 'Run available scripts which include "ruby"', "shnell run all ruby"
|
91
|
+
c.example "Dry run all available scripts (make no changes)", "shnell run all --pretend"
|
92
|
+
|
45
93
|
c.action do |args, options|
|
46
94
|
$:.unshift SCRIPTS_ROOT
|
47
95
|
script = args.shift
|
48
|
-
require 'filander'
|
49
96
|
include Filander
|
50
97
|
|
98
|
+
Filander.quiet = options.quiet
|
51
99
|
behavior = :ask
|
52
100
|
behavior = :skip if options.skip
|
53
101
|
behavior = :pretend if options.pretend
|
@@ -55,17 +103,46 @@ command :run do |c|
|
|
55
103
|
Filander.behavior = behavior
|
56
104
|
|
57
105
|
if script == "all"
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
say message
|
106
|
+
pattern = args.shift
|
107
|
+
|
108
|
+
scripts(pattern).each do |file|
|
109
|
+
say_script file, "Running", options.quiet
|
63
110
|
Filander.source_root = file.sub(/\.rb$/, '')
|
64
111
|
require file
|
65
112
|
end
|
66
|
-
|
113
|
+
elsif script
|
67
114
|
Filander.source_root = File.join(SCRIPTS_ROOT, script)
|
68
115
|
require script
|
116
|
+
else
|
117
|
+
say "No script set."
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
command :backup do |c|
|
123
|
+
c.syntax = 'shnell backup script'
|
124
|
+
c.description = 'Run a backup script.'
|
125
|
+
|
126
|
+
c.option '-q', '--quiet', 'Supress status output'
|
127
|
+
|
128
|
+
c.action do |args, options|
|
129
|
+
script = args.shift
|
130
|
+
|
131
|
+
require File.join(File.dirname(__FILE__), '../lib/backup')
|
132
|
+
include Backup
|
133
|
+
|
134
|
+
if script == "all"
|
135
|
+
pattern = args.shift
|
136
|
+
|
137
|
+
backup_scripts(pattern).each do |file|
|
138
|
+
say_script file, "Backup", options.quiet
|
139
|
+
require file
|
140
|
+
end
|
141
|
+
elsif script
|
142
|
+
require script
|
143
|
+
else
|
144
|
+
say "No backup script set."
|
69
145
|
end
|
70
146
|
end
|
71
147
|
end
|
148
|
+
|
data/lib/backup.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'net/ftp'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Backup
|
5
|
+
include Filander
|
6
|
+
|
7
|
+
class BackupScript
|
8
|
+
class << self
|
9
|
+
def backup(name, &block)
|
10
|
+
backup = self.new(name)
|
11
|
+
backup.prepare
|
12
|
+
backup.instance_eval(&block)
|
13
|
+
backup.backup!
|
14
|
+
backup.finish
|
15
|
+
end
|
16
|
+
|
17
|
+
def restore(name, &block)
|
18
|
+
backup = self.new(name)
|
19
|
+
backup.instance_eval(&block)
|
20
|
+
backup.restore!
|
21
|
+
backup.finish
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(service)
|
26
|
+
@service_root = service
|
27
|
+
@service_name = File.basename(service)
|
28
|
+
@database = @service_name.gsub(/[-\.]/, '_')
|
29
|
+
@tempdir = File.join("/tmp", @service_name)
|
30
|
+
@tarball = "#{@tempdir}.tar.bz2"
|
31
|
+
@directories = []
|
32
|
+
@databases = []
|
33
|
+
end
|
34
|
+
|
35
|
+
def prepare
|
36
|
+
backup_cmd "mkdir -p #{@tempdir}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def directory(filename)
|
40
|
+
report :directory, filename
|
41
|
+
@directories << filename
|
42
|
+
end
|
43
|
+
|
44
|
+
def database(database = @database)
|
45
|
+
report :database, database
|
46
|
+
@databases << database
|
47
|
+
end
|
48
|
+
|
49
|
+
def backup!
|
50
|
+
@directories.each do |filename|
|
51
|
+
filename = File.join(@service_root, filename)
|
52
|
+
backup_cmd "cp -r #{filename} #{@tempdir}/"
|
53
|
+
end
|
54
|
+
@databases.each do |database|
|
55
|
+
backup_cmd "mysqldump -u#{db_user} #{"-p#{db_password}" if db_password != ''} #{database} > #{File.join(@tempdir, "#{database}.sql")}"
|
56
|
+
end
|
57
|
+
backup_cmd "tar -C /tmp -cjf #{@tarball} #{@service_name}"
|
58
|
+
Net::FTP.open(ftp_host) do |ftp|
|
59
|
+
ftp.login ftp_user, ftp_password
|
60
|
+
ftp.putbinaryfile @tarball
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def restore!
|
65
|
+
Net::FTP.open(ftp_host) do |ftp|
|
66
|
+
ftp.login ftp_user, ftp_password
|
67
|
+
ftp.getbinaryfile @tarball
|
68
|
+
end
|
69
|
+
backup_cmd "tar -C /tmp -xf #{@tarball}"
|
70
|
+
@databases.each do |database|
|
71
|
+
backup_cmd "mysql -u#{db_user} #{"-p#{db_password}" if db_password != ''} #{database} < #{File.join(@tempdir, "#{database}.sql")}"
|
72
|
+
end
|
73
|
+
@directories.each do |filename|
|
74
|
+
source = File.join(@tempdir, filename)
|
75
|
+
dest = File.join(@service_root, filename)
|
76
|
+
backup_cmd "cp -r #{source} #{dest}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def finish
|
81
|
+
backup_cmd "rm -rf #{@tempdir}"
|
82
|
+
backup_cmd "rm #{@tarball}"
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def backup_cmd(command)
|
88
|
+
system command
|
89
|
+
end
|
90
|
+
|
91
|
+
def db_user
|
92
|
+
read_config(:db, :user)
|
93
|
+
end
|
94
|
+
|
95
|
+
def db_password
|
96
|
+
read_config(:db, :password)
|
97
|
+
end
|
98
|
+
|
99
|
+
def ftp_host
|
100
|
+
read_config(:ftp, :host)
|
101
|
+
end
|
102
|
+
|
103
|
+
def ftp_user
|
104
|
+
read_config(:ftp, :user)
|
105
|
+
end
|
106
|
+
|
107
|
+
def ftp_password
|
108
|
+
read_config(:ftp, :password)
|
109
|
+
end
|
110
|
+
|
111
|
+
def read_config(scope, key)
|
112
|
+
hash = config[scope.to_s] || {}
|
113
|
+
value = hash[key.to_s]
|
114
|
+
if value.nil?
|
115
|
+
question = "Give me the #{scope} #{key}:"
|
116
|
+
value = if key.to_s =~ /password/
|
117
|
+
ask(question) { |q| q.echo = "*" }
|
118
|
+
else
|
119
|
+
ask(question)
|
120
|
+
end
|
121
|
+
write_config scope, key, value
|
122
|
+
end
|
123
|
+
value
|
124
|
+
end
|
125
|
+
|
126
|
+
def write_config(scope, key, value)
|
127
|
+
hash = config
|
128
|
+
hash[scope.to_s] ||= {}
|
129
|
+
hash[scope.to_s].update key.to_s => value
|
130
|
+
File.open(CONFIG_FILENAME, "w") do |file|
|
131
|
+
file << YAML.dump(hash)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def config
|
136
|
+
content = File.read(CONFIG_FILENAME) rescue nil
|
137
|
+
return {} unless content
|
138
|
+
YAML.load(content)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def backup(filename, &block)
|
143
|
+
BackupScript.backup filename, &block
|
144
|
+
end
|
145
|
+
|
146
|
+
def restore(filename, &block)
|
147
|
+
BackupScript.restore filename, &block
|
148
|
+
end
|
149
|
+
end
|
data/lib/shnell.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 2
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Johannes J. Schmidt
|
@@ -40,9 +40,9 @@ dependencies:
|
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
segments:
|
42
42
|
- 0
|
43
|
-
-
|
43
|
+
- 5
|
44
44
|
- 0
|
45
|
-
version: 0.
|
45
|
+
version: 0.5.0
|
46
46
|
type: :runtime
|
47
47
|
version_requirements: *id002
|
48
48
|
description: Ease Server Setup and Configuration
|
@@ -55,13 +55,11 @@ extra_rdoc_files:
|
|
55
55
|
- LICENSE
|
56
56
|
- README.rdoc
|
57
57
|
files:
|
58
|
-
- .gitignore
|
59
|
-
- LICENSE
|
60
|
-
- README.rdoc
|
61
|
-
- Rakefile
|
62
58
|
- bin/shnell
|
59
|
+
- lib/backup.rb
|
63
60
|
- lib/shnell.rb
|
64
|
-
-
|
61
|
+
- LICENSE
|
62
|
+
- README.rdoc
|
65
63
|
has_rdoc: true
|
66
64
|
homepage: http://github.com/jo/shnell
|
67
65
|
licenses: []
|
data/.gitignore
DELETED
data/Rakefile
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rake'
|
3
|
-
require File.join(File.dirname(__FILE__), 'lib', 'shnell')
|
4
|
-
|
5
|
-
begin
|
6
|
-
require 'jeweler'
|
7
|
-
Jeweler::Tasks.new do |gem|
|
8
|
-
gem.name = "shnell"
|
9
|
-
gem.version = Shnell::VERSION
|
10
|
-
gem.summary = %Q{Server Setup and Configuration tools}
|
11
|
-
gem.description = %Q{Ease Server Setup and Configuration}
|
12
|
-
gem.email = "schmidt@netzmerk.com"
|
13
|
-
gem.homepage = "http://github.com/jo/shnell"
|
14
|
-
gem.authors = ["Johannes J. Schmidt"]
|
15
|
-
gem.add_dependency "commander", ">= 4.0.2"
|
16
|
-
gem.add_dependency "filander", ">= 0.4.0"
|
17
|
-
end
|
18
|
-
Jeweler::GemcutterTasks.new
|
19
|
-
rescue LoadError
|
20
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
-
end
|
22
|
-
|
23
|
-
task :default => :test
|
24
|
-
|
25
|
-
require 'rake/rdoctask'
|
26
|
-
Rake::RDocTask.new do |rdoc|
|
27
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
28
|
-
|
29
|
-
rdoc.rdoc_dir = 'rdoc'
|
30
|
-
rdoc.title = "shnell #{version}"
|
31
|
-
rdoc.rdoc_files.include('README*')
|
32
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
33
|
-
end
|
data/shnell.gemspec
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
|
-
Gem::Specification.new do |s|
|
7
|
-
s.name = %q{shnell}
|
8
|
-
s.version = "0.1.0"
|
9
|
-
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["Johannes J. Schmidt"]
|
12
|
-
s.date = %q{2010-04-08}
|
13
|
-
s.default_executable = %q{shnell}
|
14
|
-
s.description = %q{Ease Server Setup and Configuration}
|
15
|
-
s.email = %q{schmidt@netzmerk.com}
|
16
|
-
s.executables = ["shnell"]
|
17
|
-
s.extra_rdoc_files = [
|
18
|
-
"LICENSE",
|
19
|
-
"README.rdoc"
|
20
|
-
]
|
21
|
-
s.files = [
|
22
|
-
".gitignore",
|
23
|
-
"LICENSE",
|
24
|
-
"README.rdoc",
|
25
|
-
"Rakefile",
|
26
|
-
"bin/shnell",
|
27
|
-
"lib/shnell.rb",
|
28
|
-
"shnell.gemspec"
|
29
|
-
]
|
30
|
-
s.homepage = %q{http://github.com/jo/shnell}
|
31
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
32
|
-
s.require_paths = ["lib"]
|
33
|
-
s.rubygems_version = %q{1.3.6}
|
34
|
-
s.summary = %q{Server Setup and Configuration tools}
|
35
|
-
|
36
|
-
if s.respond_to? :specification_version then
|
37
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
38
|
-
s.specification_version = 3
|
39
|
-
|
40
|
-
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
41
|
-
s.add_runtime_dependency(%q<commander>, [">= 4.0.2"])
|
42
|
-
s.add_runtime_dependency(%q<filander>, [">= 0.4.0"])
|
43
|
-
else
|
44
|
-
s.add_dependency(%q<commander>, [">= 4.0.2"])
|
45
|
-
s.add_dependency(%q<filander>, [">= 0.4.0"])
|
46
|
-
end
|
47
|
-
else
|
48
|
-
s.add_dependency(%q<commander>, [">= 4.0.2"])
|
49
|
-
s.add_dependency(%q<filander>, [">= 0.4.0"])
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|