dosh 0.0.1
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/.gitignore +17 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +34 -0
- data/Rakefile +1 -0
- data/bin/dosh +12 -0
- data/dosh.gemspec +23 -0
- data/generic/example.rb +10 -0
- data/generic/fail.rb +6 -0
- data/generic/version.rb +5 -0
- data/lib/dosh.rb +8 -0
- data/lib/platform.rb +15 -0
- data/lib/script.rb +130 -0
- data/lib/shelling.rb +17 -0
- data/lib/terminal.rb +44 -0
- data/ubuntu/ensure_passwordless_sudo.sh +3 -0
- data/ubuntu/install_apt_key.rb +15 -0
- data/ubuntu/install_apt_source.rb +15 -0
- data/ubuntu/install_mongodb.rb +7 -0
- data/ubuntu/install_openjdk.rb +17 -0
- data/ubuntu/meet_apt_install.rb +13 -0
- data/ubuntu/meet_apt_updated_and_upgraded.rb +8 -0
- metadata +101 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 Jon Williams
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Dosh
|
|
2
|
+
|
|
3
|
+
Dev Ops Scripting.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
$ gem install dosh
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
Ruby 1.9.3 or greater.
|
|
12
|
+
|
|
13
|
+
## Principles
|
|
14
|
+
|
|
15
|
+
1. Scripts should be standalone.
|
|
16
|
+
2. DRY, but self-sufficency and explictness are important too.
|
|
17
|
+
3. Scripts should be re-runnable, with the same outcome. If something changes
|
|
18
|
+
that can't be repeated, check for it and exit early.
|
|
19
|
+
|
|
20
|
+
## Conventions
|
|
21
|
+
|
|
22
|
+
- "ensure_<state>" checks if a state is true, generating a fault if not.
|
|
23
|
+
- "install_<noun>" installs the given noun, to a completely "ready" state.
|
|
24
|
+
- "meet_<noun>_<state>" takes the noun and attemps to achieve the given state.
|
|
25
|
+
|
|
26
|
+
## Contributing
|
|
27
|
+
|
|
28
|
+
1. Fork it
|
|
29
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
30
|
+
2a. Make sure you have some tests or way of validating the feature.
|
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
33
|
+
5. Create new Pull Request
|
|
34
|
+
6. ... and thanks!
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/dosh
ADDED
data/dosh.gemspec
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'dosh'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "dosh"
|
|
8
|
+
spec.version = Dosh::VERSION
|
|
9
|
+
spec.authors = ["Jon Williams"]
|
|
10
|
+
spec.email = ["jon@jonathannen.com"]
|
|
11
|
+
spec.description = %q{Dev Ops Scripting}
|
|
12
|
+
spec.summary = %q{Dev Ops Scripting}
|
|
13
|
+
spec.homepage = "https://github.com/jonathannen/dosh"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
|
22
|
+
spec.add_development_dependency "rake"
|
|
23
|
+
end
|
data/generic/example.rb
ADDED
data/generic/fail.rb
ADDED
data/generic/version.rb
ADDED
data/lib/dosh.rb
ADDED
data/lib/platform.rb
ADDED
data/lib/script.rb
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'benchmark'
|
|
3
|
+
|
|
4
|
+
use_color = !ARGV.include?('--no-color')
|
|
5
|
+
|
|
6
|
+
module Dosh
|
|
7
|
+
EXPLICIT_EXTENSIONS = ['.rb', '.sh']
|
|
8
|
+
|
|
9
|
+
module Injection
|
|
10
|
+
|
|
11
|
+
def script(*args, &block)
|
|
12
|
+
s = Script.new
|
|
13
|
+
s.script(*args, &block)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Script
|
|
19
|
+
include Shelling
|
|
20
|
+
include Terminal
|
|
21
|
+
@@dosh_dir = File.expand_path(File.join(File.dirname(File.expand_path(__FILE__)), '..'))
|
|
22
|
+
|
|
23
|
+
def initialize(use_require = false)
|
|
24
|
+
@use_require = use_require
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def candidate_files(filename)
|
|
28
|
+
fn = [filename]
|
|
29
|
+
fn += EXPLICIT_EXTENSIONS.map { |ext| "#{filename}#{ext}"} unless has_explicit_extension?(filename)
|
|
30
|
+
fn += fn.product(platform_prefixes).map { |file, dir| File.join(dir, file) }
|
|
31
|
+
fn.product([@@dosh_dir, Dir.pwd]).map { |file, dir| File.join(dir, file) }.uniq
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def resolve_file(filename)
|
|
35
|
+
candidate_files(filename).detect { |file| File.exists?(file) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def script(*args, &block)
|
|
39
|
+
if args.first == :meet
|
|
40
|
+
command = args.first
|
|
41
|
+
task = Meet.new
|
|
42
|
+
task.instance_eval(&block)
|
|
43
|
+
else
|
|
44
|
+
filename = nil
|
|
45
|
+
command = args.shift
|
|
46
|
+
if @use_require || !File.exists?(command)
|
|
47
|
+
filename = resolve_file(command)
|
|
48
|
+
end
|
|
49
|
+
task = @use_require ? Require.new(filename, args) : Standard.new(filename, command, args)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
raise "#{command} failed" unless run_dependency(command, task, &block)
|
|
53
|
+
|
|
54
|
+
rescue Exception => e
|
|
55
|
+
raise e
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
protected
|
|
59
|
+
|
|
60
|
+
def has_explicit_extension?(filename)
|
|
61
|
+
!!EXPLICIT_EXTENSIONS.detect { |ext| filename.end_with?(ext) }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def run_dependency(header, task, &block)
|
|
65
|
+
current = ENV['DOSH_INDENT'] || ""
|
|
66
|
+
log_started(header)
|
|
67
|
+
ENV['DOSH_INDENT'] = "#{current} "
|
|
68
|
+
result = task.run(&block)
|
|
69
|
+
ENV['DOSH_INDENT'] = current
|
|
70
|
+
|
|
71
|
+
result ? log_success(header) : log_failure(header)
|
|
72
|
+
result
|
|
73
|
+
rescue Exception => e
|
|
74
|
+
puts e.message
|
|
75
|
+
puts e.backtrace
|
|
76
|
+
ENV['DOSH_INDENT'] = current
|
|
77
|
+
log_failure(header)
|
|
78
|
+
raise e
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class Meet < Script
|
|
85
|
+
|
|
86
|
+
def run
|
|
87
|
+
return true if self.met?
|
|
88
|
+
meet
|
|
89
|
+
self.met?
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
class Require < Script
|
|
95
|
+
|
|
96
|
+
def initialize(filename, args)
|
|
97
|
+
@filename = filename
|
|
98
|
+
@args = args
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def run
|
|
102
|
+
raise "File '#{command}' not found" if @filename.nil?
|
|
103
|
+
ARGV.clear
|
|
104
|
+
@args.each { |a| ARGV << a }
|
|
105
|
+
require(@filename)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
class Standard < Script
|
|
111
|
+
|
|
112
|
+
def initialize(filename, command, args)
|
|
113
|
+
@filename = filename
|
|
114
|
+
@command = command
|
|
115
|
+
@args = args
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def run(&block)
|
|
119
|
+
raise "File '#{@filename}' not executable" if !@filename.nil? && !File.executable?(@filename)
|
|
120
|
+
system(@filename || @command, *@args)
|
|
121
|
+
success = $?.success?
|
|
122
|
+
self.instance_eval(&block) if success && block_given?
|
|
123
|
+
success
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
Object.send(:include, Dosh::Injection)
|
data/lib/shelling.rb
ADDED
data/lib/terminal.rb
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Dosh
|
|
3
|
+
|
|
4
|
+
module Terminal
|
|
5
|
+
|
|
6
|
+
protected
|
|
7
|
+
|
|
8
|
+
COLORS = %w{black red green yellow blue magenta cyan grey}
|
|
9
|
+
|
|
10
|
+
COLORS.each_with_index do |value, i|
|
|
11
|
+
define_method(value.to_sym) { |v| "\e[0;3#{i}m#{v}\e[0m" }
|
|
12
|
+
|
|
13
|
+
if value == 'grey'
|
|
14
|
+
define_method(:gray) { |v| "\e[0;3#{i}m#{v}\e[0m" }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def white(v)
|
|
19
|
+
"\e[0m#{v}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def indentation
|
|
23
|
+
ENV['DOSH_INDENT']
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def log_failure(*args)
|
|
27
|
+
puts "#{indentation}#{red('✘')} #{args * ' '}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def log_general(*args)
|
|
31
|
+
puts "#{indentation}#{args * ' '}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def log_started(*args)
|
|
35
|
+
puts "#{indentation}> #{grey(args * ' ')}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def log_success(*args)
|
|
39
|
+
puts "#{indentation}#{green('✔')} #{args * ' '}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
# install_apt_key.rb <recv> [keyserver]
|
|
4
|
+
|
|
5
|
+
recv = ARGV.shift
|
|
6
|
+
keyserver = ARGV.shift || 'hkp://keyserver.ubuntu.com:80'
|
|
7
|
+
puts("The apt-key recv value is required") & exit(1) if recv.nil?
|
|
8
|
+
|
|
9
|
+
def met?(recv)
|
|
10
|
+
`sudo apt-key list | grep #{recv}`.length > 0
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
exit(0) if met?(recv)
|
|
14
|
+
system "sudo apt-key adv --keyserver #{keyserver} --recv #{recv}"
|
|
15
|
+
exit(met?(recv) ? 0 : 1)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
# install_apt_source.rb <entry>
|
|
4
|
+
|
|
5
|
+
puts("Entry must be supplied. Something like \"deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen\"") & exit(1) if ARGV.length == 0
|
|
6
|
+
entry = ARGV * ' '
|
|
7
|
+
|
|
8
|
+
def met?(entry)
|
|
9
|
+
`cat /etc/apt/sources.list`.lines.detect { |v| v.strip == entry }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
exit(0) if met?(entry)
|
|
13
|
+
system "echo '#{entry}' | sudo tee -a /etc/apt/sources.list"
|
|
14
|
+
system "sudo apt-get -y --force-yes update"
|
|
15
|
+
exit(met?(entry) ? 0 : 1)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env dosh -r
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
# Installs MongoDB via the 10gen repository.
|
|
4
|
+
|
|
5
|
+
script 'install_apt_key', '7F0CEB10'
|
|
6
|
+
script 'install_apt_source', 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen'
|
|
7
|
+
script 'meet_apt_install', 'mongodb-10gen'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env dosh -r
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
# install_openjdk [version]
|
|
4
|
+
# version: "7" would install Java7. This is the default.
|
|
5
|
+
|
|
6
|
+
script(:meet) do
|
|
7
|
+
@version = ARGV.shift || "7"
|
|
8
|
+
|
|
9
|
+
def met?
|
|
10
|
+
shell("java -version 2>&1").include?("version \"1.#{@version}.")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def meet
|
|
14
|
+
script 'meet_apt_install', "openjdk-#{@version}-jdk"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
# meet_apt_install.rb <package1> [package2..]
|
|
4
|
+
|
|
5
|
+
puts("At least one package is required") & exit(1) if ARGV.length == 0
|
|
6
|
+
|
|
7
|
+
def met?(names)
|
|
8
|
+
!names.detect { |name| `dpkg -s #{name}`; !$?.success? }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
exit(0) if met?(ARGV)
|
|
12
|
+
system "sudo apt-get -y --force-yes install #{ARGV * ' '}"
|
|
13
|
+
exit(met?(ARGV) ? 0 : 1)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env dosh -r
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
# Performs an update and update of aptitude. Will attempt to do so unattended.
|
|
4
|
+
|
|
5
|
+
script 'ensure_passwordless_sudo'
|
|
6
|
+
script "sudo apt-get -y --force-yes update"
|
|
7
|
+
script "sudo apt-get -y --force-yes upgrade"
|
|
8
|
+
script "sudo apt-get -y --force-yes clean"
|
metadata
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dosh
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Jon Williams
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2013-06-30 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: bundler
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ~>
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '1.3'
|
|
22
|
+
type: :development
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '1.3'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: rake
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
34
|
+
requirements:
|
|
35
|
+
- - ! '>='
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '0'
|
|
38
|
+
type: :development
|
|
39
|
+
prerelease: false
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ! '>='
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
46
|
+
description: Dev Ops Scripting
|
|
47
|
+
email:
|
|
48
|
+
- jon@jonathannen.com
|
|
49
|
+
executables:
|
|
50
|
+
- dosh
|
|
51
|
+
extensions: []
|
|
52
|
+
extra_rdoc_files: []
|
|
53
|
+
files:
|
|
54
|
+
- .gitignore
|
|
55
|
+
- Gemfile
|
|
56
|
+
- LICENSE.txt
|
|
57
|
+
- README.md
|
|
58
|
+
- Rakefile
|
|
59
|
+
- bin/dosh
|
|
60
|
+
- dosh.gemspec
|
|
61
|
+
- generic/example.rb
|
|
62
|
+
- generic/fail.rb
|
|
63
|
+
- generic/version.rb
|
|
64
|
+
- lib/dosh.rb
|
|
65
|
+
- lib/platform.rb
|
|
66
|
+
- lib/script.rb
|
|
67
|
+
- lib/shelling.rb
|
|
68
|
+
- lib/terminal.rb
|
|
69
|
+
- ubuntu/ensure_passwordless_sudo.sh
|
|
70
|
+
- ubuntu/install_apt_key.rb
|
|
71
|
+
- ubuntu/install_apt_source.rb
|
|
72
|
+
- ubuntu/install_mongodb.rb
|
|
73
|
+
- ubuntu/install_openjdk.rb
|
|
74
|
+
- ubuntu/meet_apt_install.rb
|
|
75
|
+
- ubuntu/meet_apt_updated_and_upgraded.rb
|
|
76
|
+
homepage: https://github.com/jonathannen/dosh
|
|
77
|
+
licenses:
|
|
78
|
+
- MIT
|
|
79
|
+
post_install_message:
|
|
80
|
+
rdoc_options: []
|
|
81
|
+
require_paths:
|
|
82
|
+
- lib
|
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
|
+
none: false
|
|
85
|
+
requirements:
|
|
86
|
+
- - ! '>='
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
|
+
none: false
|
|
91
|
+
requirements:
|
|
92
|
+
- - ! '>='
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '0'
|
|
95
|
+
requirements: []
|
|
96
|
+
rubyforge_project:
|
|
97
|
+
rubygems_version: 1.8.25
|
|
98
|
+
signing_key:
|
|
99
|
+
specification_version: 3
|
|
100
|
+
summary: Dev Ops Scripting
|
|
101
|
+
test_files: []
|